summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan
authorzautrix <zautrix>2004-07-03 16:33:12 (UTC)
committer zautrix <zautrix>2004-07-03 16:33:12 (UTC)
commite3b89230f065c48c84b48c88edb6eb088374c487 (patch) (unidiff)
tree162ea2ef909a6f82ccfcedf45d80d6c821174912 /kmicromail/libetpan
parent2dd6ac0b2d24c91d35ce674a6c26351352df2b15 (diff)
downloadkdepimpi-e3b89230f065c48c84b48c88edb6eb088374c487.zip
kdepimpi-e3b89230f065c48c84b48c88edb6eb088374c487.tar.gz
kdepimpi-e3b89230f065c48c84b48c88edb6eb088374c487.tar.bz2
Initial revision
Diffstat (limited to 'kmicromail/libetpan') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/config.h112
-rw-r--r--kmicromail/libetpan/doc/API.sgml15097
-rw-r--r--kmicromail/libetpan/doc/DOCUMENTATION654
-rw-r--r--kmicromail/libetpan/doc/README.sgml319
-rw-r--r--kmicromail/libetpan/doc/depend.dot54
-rw-r--r--kmicromail/libetpan/doc/layer.fig39
-rw-r--r--kmicromail/libetpan/generic/.libs/libmaildriver.abin0 -> 1412946 bytes
-rw-r--r--kmicromail/libetpan/generic/TODO9
-rw-r--r--kmicromail/libetpan/generic/data_message_driver.c119
-rw-r--r--kmicromail/libetpan/generic/data_message_driver.h50
-rw-r--r--kmicromail/libetpan/generic/generic_cache.c729
-rw-r--r--kmicromail/libetpan/generic/generic_cache.h109
-rw-r--r--kmicromail/libetpan/generic/generic_cache_types.h56
-rw-r--r--kmicromail/libetpan/generic/imapdriver.c1130
-rw-r--r--kmicromail/libetpan/generic/imapdriver.h52
-rw-r--r--kmicromail/libetpan/generic/imapdriver_cached.c1274
-rw-r--r--kmicromail/libetpan/generic/imapdriver_cached.h52
-rw-r--r--kmicromail/libetpan/generic/imapdriver_cached_message.c664
-rw-r--r--kmicromail/libetpan/generic/imapdriver_cached_message.h52
-rw-r--r--kmicromail/libetpan/generic/imapdriver_message.c1239
-rw-r--r--kmicromail/libetpan/generic/imapdriver_message.h52
-rw-r--r--kmicromail/libetpan/generic/imapdriver_tools.c3599
-rw-r--r--kmicromail/libetpan/generic/imapdriver_tools.h113
-rw-r--r--kmicromail/libetpan/generic/imapdriver_types.h144
-rw-r--r--kmicromail/libetpan/generic/imapstorage.c297
-rw-r--r--kmicromail/libetpan/generic/imapstorage.h90
-rw-r--r--kmicromail/libetpan/generic/imfcache.c1429
-rw-r--r--kmicromail/libetpan/generic/imfcache.h75
-rw-r--r--kmicromail/libetpan/generic/libetpan.h104
-rw-r--r--kmicromail/libetpan/generic/libetpan_version.c18
-rw-r--r--kmicromail/libetpan/generic/libetpan_version.h51
-rw-r--r--kmicromail/libetpan/generic/libetpan_version.h.in51
-rw-r--r--kmicromail/libetpan/generic/maildirdriver.c625
-rw-r--r--kmicromail/libetpan/generic/maildirdriver.h53
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_cached.c1080
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_cached.h53
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_cached_message.c248
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_cached_message.h52
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_message.c199
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_message.h52
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_tools.c195
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_tools.h53
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_types.h96
-rw-r--r--kmicromail/libetpan/generic/maildirstorage.c192
-rw-r--r--kmicromail/libetpan/generic/maildirstorage.h69
-rw-r--r--kmicromail/libetpan/generic/maildriver.c373
-rw-r--r--kmicromail/libetpan/generic/maildriver.h543
-rw-r--r--kmicromail/libetpan/generic/maildriver_errors.h99
-rw-r--r--kmicromail/libetpan/generic/maildriver_tools.c841
-rw-r--r--kmicromail/libetpan/generic/maildriver_tools.h81
-rw-r--r--kmicromail/libetpan/generic/maildriver_types.c340
-rw-r--r--kmicromail/libetpan/generic/maildriver_types.h793
-rw-r--r--kmicromail/libetpan/generic/maildriver_types_helper.c104
-rw-r--r--kmicromail/libetpan/generic/maildriver_types_helper.h99
-rw-r--r--kmicromail/libetpan/generic/mailfolder.c96
-rw-r--r--kmicromail/libetpan/generic/mailfolder.h32
-rw-r--r--kmicromail/libetpan/generic/mailmessage.c240
-rw-r--r--kmicromail/libetpan/generic/mailmessage.h379
-rw-r--r--kmicromail/libetpan/generic/mailmessage_tools.c600
-rw-r--r--kmicromail/libetpan/generic/mailmessage_tools.h103
-rw-r--r--kmicromail/libetpan/generic/mailmessage_types.c92
-rw-r--r--kmicromail/libetpan/generic/mailmessage_types.h50
-rw-r--r--kmicromail/libetpan/generic/mailstorage.c334
-rw-r--r--kmicromail/libetpan/generic/mailstorage.h98
-rw-r--r--kmicromail/libetpan/generic/mailstorage_tools.c372
-rw-r--r--kmicromail/libetpan/generic/mailstorage_tools.h67
-rw-r--r--kmicromail/libetpan/generic/mailstorage_types.h203
-rw-r--r--kmicromail/libetpan/generic/mailthread.c1631
-rw-r--r--kmicromail/libetpan/generic/mailthread.h108
-rw-r--r--kmicromail/libetpan/generic/mailthread_types.c90
-rw-r--r--kmicromail/libetpan/generic/mailthread_types.h63
-rw-r--r--kmicromail/libetpan/generic/mboxdriver.c505
-rw-r--r--kmicromail/libetpan/generic/mboxdriver.h52
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_cached.c1253
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_cached.h54
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_cached_message.c360
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_cached_message.h52
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_message.c225
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_message.h52
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_tools.c434
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_tools.h85
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_types.h107
-rw-r--r--kmicromail/libetpan/generic/mboxstorage.c192
-rw-r--r--kmicromail/libetpan/generic/mboxstorage.h69
-rw-r--r--kmicromail/libetpan/generic/mhdriver.c866
-rw-r--r--kmicromail/libetpan/generic/mhdriver.h52
-rw-r--r--kmicromail/libetpan/generic/mhdriver_cached.c1232
-rw-r--r--kmicromail/libetpan/generic/mhdriver_cached.h52
-rw-r--r--kmicromail/libetpan/generic/mhdriver_cached_message.c338
-rw-r--r--kmicromail/libetpan/generic/mhdriver_cached_message.h52
-rw-r--r--kmicromail/libetpan/generic/mhdriver_message.c212
-rw-r--r--kmicromail/libetpan/generic/mhdriver_message.h52
-rw-r--r--kmicromail/libetpan/generic/mhdriver_tools.c475
-rw-r--r--kmicromail/libetpan/generic/mhdriver_tools.h80
-rw-r--r--kmicromail/libetpan/generic/mhdriver_types.h100
-rw-r--r--kmicromail/libetpan/generic/mhstorage.c192
-rw-r--r--kmicromail/libetpan/generic/mhstorage.h67
-rw-r--r--kmicromail/libetpan/generic/mime_message_driver.c689
-rw-r--r--kmicromail/libetpan/generic/mime_message_driver.h52
-rw-r--r--kmicromail/libetpan/generic/nntpdriver.c1170
-rw-r--r--kmicromail/libetpan/generic/nntpdriver.h52
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_cached.c1048
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_cached.h52
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_cached_message.c365
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_cached_message.h52
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_message.c169
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_message.h52
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_tools.c563
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_tools.h88
-rw-r--r--kmicromail/libetpan/generic/nntpdriver_types.h146
-rw-r--r--kmicromail/libetpan/generic/nntpstorage.c267
-rw-r--r--kmicromail/libetpan/generic/nntpstorage.h93
-rw-r--r--kmicromail/libetpan/generic/pop3driver.c387
-rw-r--r--kmicromail/libetpan/generic/pop3driver.h52
-rw-r--r--kmicromail/libetpan/generic/pop3driver_cached.c857
-rw-r--r--kmicromail/libetpan/generic/pop3driver_cached.h52
-rw-r--r--kmicromail/libetpan/generic/pop3driver_cached_message.c355
-rw-r--r--kmicromail/libetpan/generic/pop3driver_cached_message.h52
-rw-r--r--kmicromail/libetpan/generic/pop3driver_message.c159
-rw-r--r--kmicromail/libetpan/generic/pop3driver_message.h52
-rw-r--r--kmicromail/libetpan/generic/pop3driver_tools.c344
-rw-r--r--kmicromail/libetpan/generic/pop3driver_tools.h82
-rw-r--r--kmicromail/libetpan/generic/pop3driver_types.h153
-rw-r--r--kmicromail/libetpan/generic/pop3storage.c284
-rw-r--r--kmicromail/libetpan/generic/pop3storage.h95
-rw-r--r--kmicromail/libetpan/imap/.libs/libmailimap.abin0 -> 451562 bytes
-rw-r--r--kmicromail/libetpan/imap/TODO4
-rw-r--r--kmicromail/libetpan/imap/mailimap.c2161
-rw-r--r--kmicromail/libetpan/imap/mailimap.h598
-rw-r--r--kmicromail/libetpan/imap/mailimap_helper.c205
-rw-r--r--kmicromail/libetpan/imap/mailimap_helper.h66
-rw-r--r--kmicromail/libetpan/imap/mailimap_keywords.c353
-rw-r--r--kmicromail/libetpan/imap/mailimap_keywords.h107
-rw-r--r--kmicromail/libetpan/imap/mailimap_parser.c9506
-rw-r--r--kmicromail/libetpan/imap/mailimap_parser.h69
-rw-r--r--kmicromail/libetpan/imap/mailimap_print.c1615
-rw-r--r--kmicromail/libetpan/imap/mailimap_print.h54
-rw-r--r--kmicromail/libetpan/imap/mailimap_sender.c2743
-rw-r--r--kmicromail/libetpan/imap/mailimap_sender.h164
-rw-r--r--kmicromail/libetpan/imap/mailimap_socket.c73
-rw-r--r--kmicromail/libetpan/imap/mailimap_socket.h54
-rw-r--r--kmicromail/libetpan/imap/mailimap_ssl.c73
-rw-r--r--kmicromail/libetpan/imap/mailimap_ssl.h54
-rw-r--r--kmicromail/libetpan/imap/mailimap_types.c2961
-rw-r--r--kmicromail/libetpan/imap/mailimap_types.h3274
-rw-r--r--kmicromail/libetpan/imap/mailimap_types_helper.c1269
-rw-r--r--kmicromail/libetpan/imap/mailimap_types_helper.h758
-rw-r--r--kmicromail/libetpan/imf/.libs/libmailimf.abin0 -> 201426 bytes
-rw-r--r--kmicromail/libetpan/imf/TODO16
-rw-r--r--kmicromail/libetpan/imf/mailimf.c7585
-rw-r--r--kmicromail/libetpan/imf/mailimf.h345
-rw-r--r--kmicromail/libetpan/imf/mailimf_types.c868
-rw-r--r--kmicromail/libetpan/imf/mailimf_types.h793
-rw-r--r--kmicromail/libetpan/imf/mailimf_types_helper.c1636
-rw-r--r--kmicromail/libetpan/imf/mailimf_types_helper.h370
-rw-r--r--kmicromail/libetpan/imf/mailimf_write.c2021
-rw-r--r--kmicromail/libetpan/imf/mailimf_write.h134
-rw-r--r--kmicromail/libetpan/include/libetpan/carray.h124
-rw-r--r--kmicromail/libetpan/include/libetpan/charconv.h67
-rw-r--r--kmicromail/libetpan/include/libetpan/chash.h166
-rw-r--r--kmicromail/libetpan/include/libetpan/cinthash.h69
-rw-r--r--kmicromail/libetpan/include/libetpan/clist.h134
-rw-r--r--kmicromail/libetpan/include/libetpan/data_message_driver.h50
-rw-r--r--kmicromail/libetpan/include/libetpan/generic_cache_types.h56
-rw-r--r--kmicromail/libetpan/include/libetpan/imapdriver.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/imapdriver_cached.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/imapdriver_cached_message.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/imapdriver_message.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/imapdriver_types.h144
-rw-r--r--kmicromail/libetpan/include/libetpan/imapstorage.h90
-rw-r--r--kmicromail/libetpan/include/libetpan/libetpan-config.h7
-rw-r--r--kmicromail/libetpan/include/libetpan/libetpan.h104
-rw-r--r--kmicromail/libetpan/include/libetpan/libetpan_version.h51
-rw-r--r--kmicromail/libetpan/include/libetpan/mail.h56
-rw-r--r--kmicromail/libetpan/include/libetpan/maildir.h60
-rw-r--r--kmicromail/libetpan/include/libetpan/maildir_types.h90
-rw-r--r--kmicromail/libetpan/include/libetpan/maildirdriver.h53
-rw-r--r--kmicromail/libetpan/include/libetpan/maildirdriver_cached.h53
-rw-r--r--kmicromail/libetpan/include/libetpan/maildirdriver_cached_message.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/maildirdriver_message.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/maildirdriver_types.h96
-rw-r--r--kmicromail/libetpan/include/libetpan/maildirstorage.h69
-rw-r--r--kmicromail/libetpan/include/libetpan/maildriver.h543
-rw-r--r--kmicromail/libetpan/include/libetpan/maildriver_errors.h99
-rw-r--r--kmicromail/libetpan/include/libetpan/maildriver_types.h793
-rw-r--r--kmicromail/libetpan/include/libetpan/maildriver_types_helper.h99
-rw-r--r--kmicromail/libetpan/include/libetpan/mailfolder.h32
-rw-r--r--kmicromail/libetpan/include/libetpan/mailimap.h598
-rw-r--r--kmicromail/libetpan/include/libetpan/mailimap_helper.h66
-rw-r--r--kmicromail/libetpan/include/libetpan/mailimap_socket.h54
-rw-r--r--kmicromail/libetpan/include/libetpan/mailimap_ssl.h54
-rw-r--r--kmicromail/libetpan/include/libetpan/mailimap_types.h3274
-rw-r--r--kmicromail/libetpan/include/libetpan/mailimap_types_helper.h758
-rw-r--r--kmicromail/libetpan/include/libetpan/mailimf.h345
-rw-r--r--kmicromail/libetpan/include/libetpan/mailimf_types.h793
-rw-r--r--kmicromail/libetpan/include/libetpan/mailimf_types_helper.h370
-rw-r--r--kmicromail/libetpan/include/libetpan/mailimf_write.h134
-rw-r--r--kmicromail/libetpan/include/libetpan/mailmbox.h140
-rw-r--r--kmicromail/libetpan/include/libetpan/mailmbox_types.h142
-rw-r--r--kmicromail/libetpan/include/libetpan/mailmessage.h379
-rw-r--r--kmicromail/libetpan/include/libetpan/mailmessage_types.h50
-rw-r--r--kmicromail/libetpan/include/libetpan/mailmh.h143
-rw-r--r--kmicromail/libetpan/include/libetpan/mailmime.h100
-rw-r--r--kmicromail/libetpan/include/libetpan/mailmime_content.h89
-rw-r--r--kmicromail/libetpan/include/libetpan/mailmime_decode.h55
-rw-r--r--kmicromail/libetpan/include/libetpan/mailmime_disposition.h62
-rw-r--r--kmicromail/libetpan/include/libetpan/mailmime_types.h440
-rw-r--r--kmicromail/libetpan/include/libetpan/mailmime_types_helper.h165
-rw-r--r--kmicromail/libetpan/include/libetpan/mailmime_write.h73
-rw-r--r--kmicromail/libetpan/include/libetpan/mailpop3.h100
-rw-r--r--kmicromail/libetpan/include/libetpan/mailpop3_helper.h64
-rw-r--r--kmicromail/libetpan/include/libetpan/mailpop3_socket.h54
-rw-r--r--kmicromail/libetpan/include/libetpan/mailpop3_ssl.h54
-rw-r--r--kmicromail/libetpan/include/libetpan/mailpop3_types.h107
-rw-r--r--kmicromail/libetpan/include/libetpan/mailsmtp.h94
-rw-r--r--kmicromail/libetpan/include/libetpan/mailsmtp_helper.h74
-rw-r--r--kmicromail/libetpan/include/libetpan/mailsmtp_socket.h56
-rw-r--r--kmicromail/libetpan/include/libetpan/mailsmtp_ssl.h55
-rw-r--r--kmicromail/libetpan/include/libetpan/mailsmtp_types.h126
-rw-r--r--kmicromail/libetpan/include/libetpan/mailstorage.h98
-rw-r--r--kmicromail/libetpan/include/libetpan/mailstorage_types.h203
-rw-r--r--kmicromail/libetpan/include/libetpan/mailstream.h73
-rw-r--r--kmicromail/libetpan/include/libetpan/mailstream_helper.h70
-rw-r--r--kmicromail/libetpan/include/libetpan/mailstream_low.h62
-rw-r--r--kmicromail/libetpan/include/libetpan/mailstream_socket.h61
-rw-r--r--kmicromail/libetpan/include/libetpan/mailstream_ssl.h59
-rw-r--r--kmicromail/libetpan/include/libetpan/mailstream_types.h87
-rw-r--r--kmicromail/libetpan/include/libetpan/mailthread.h108
-rw-r--r--kmicromail/libetpan/include/libetpan/mailthread_types.h63
-rw-r--r--kmicromail/libetpan/include/libetpan/mboxdriver.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/mboxdriver_cached.h54
-rw-r--r--kmicromail/libetpan/include/libetpan/mboxdriver_cached_message.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/mboxdriver_message.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/mboxdriver_types.h107
-rw-r--r--kmicromail/libetpan/include/libetpan/mboxstorage.h69
-rw-r--r--kmicromail/libetpan/include/libetpan/mhdriver.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/mhdriver_cached.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/mhdriver_cached_message.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/mhdriver_message.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/mhdriver_types.h100
-rw-r--r--kmicromail/libetpan/include/libetpan/mhstorage.h67
-rw-r--r--kmicromail/libetpan/include/libetpan/mime_message_driver.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/mmapstring.h136
-rw-r--r--kmicromail/libetpan/include/libetpan/newsnntp.h188
-rw-r--r--kmicromail/libetpan/include/libetpan/newsnntp_socket.h55
-rw-r--r--kmicromail/libetpan/include/libetpan/newsnntp_ssl.h55
-rw-r--r--kmicromail/libetpan/include/libetpan/newsnntp_types.h144
-rw-r--r--kmicromail/libetpan/include/libetpan/nntpdriver.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/nntpdriver_cached.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/nntpdriver_cached_message.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/nntpdriver_message.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/nntpdriver_types.h146
-rw-r--r--kmicromail/libetpan/include/libetpan/nntpstorage.h93
-rw-r--r--kmicromail/libetpan/include/libetpan/pop3driver.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/pop3driver_cached.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/pop3driver_cached_message.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/pop3driver_message.h52
-rw-r--r--kmicromail/libetpan/include/libetpan/pop3driver_types.h153
-rw-r--r--kmicromail/libetpan/include/libetpan/pop3storage.h95
-rw-r--r--kmicromail/libetpan/libetpan-config.h7
-rw-r--r--kmicromail/libetpan/libetpanE.pro274
-rw-r--r--kmicromail/libetpan/maildir/.libs/libmaildir.abin0 -> 21790 bytes
-rw-r--r--kmicromail/libetpan/maildir/maildir.c710
-rw-r--r--kmicromail/libetpan/maildir/maildir.h60
-rw-r--r--kmicromail/libetpan/maildir/maildir_types.h90
-rw-r--r--kmicromail/libetpan/mbox/.libs/libmailmbox.abin0 -> 63290 bytes
-rw-r--r--kmicromail/libetpan/mbox/TODO0
-rw-r--r--kmicromail/libetpan/mbox/mailmbox.c1424
-rw-r--r--kmicromail/libetpan/mbox/mailmbox.h140
-rw-r--r--kmicromail/libetpan/mbox/mailmbox_parse.c620
-rw-r--r--kmicromail/libetpan/mbox/mailmbox_parse.h56
-rw-r--r--kmicromail/libetpan/mbox/mailmbox_types.c250
-rw-r--r--kmicromail/libetpan/mbox/mailmbox_types.h142
-rw-r--r--kmicromail/libetpan/mh/.libs/libmailmh.abin0 -> 27460 bytes
-rw-r--r--kmicromail/libetpan/mh/mailmh.c965
-rw-r--r--kmicromail/libetpan/mh/mailmh.h143
-rw-r--r--kmicromail/libetpan/mime/.libs/libmailmime.abin0 -> 192784 bytes
-rw-r--r--kmicromail/libetpan/mime/TODO10
-rw-r--r--kmicromail/libetpan/mime/mailmime.c1408
-rw-r--r--kmicromail/libetpan/mime/mailmime.h100
-rw-r--r--kmicromail/libetpan/mime/mailmime_content.c2164
-rw-r--r--kmicromail/libetpan/mime/mailmime_content.h89
-rw-r--r--kmicromail/libetpan/mime/mailmime_decode.c533
-rw-r--r--kmicromail/libetpan/mime/mailmime_decode.h55
-rw-r--r--kmicromail/libetpan/mime/mailmime_disposition.c595
-rw-r--r--kmicromail/libetpan/mime/mailmime_disposition.h62
-rw-r--r--kmicromail/libetpan/mime/mailmime_types.c750
-rw-r--r--kmicromail/libetpan/mime/mailmime_types.h440
-rw-r--r--kmicromail/libetpan/mime/mailmime_types_helper.c1385
-rw-r--r--kmicromail/libetpan/mime/mailmime_types_helper.h165
-rw-r--r--kmicromail/libetpan/mime/mailmime_write.c1416
-rw-r--r--kmicromail/libetpan/mime/mailmime_write.h73
-rw-r--r--kmicromail/libetpan/nntp/.libs/libnewsnntp.abin0 -> 69418 bytes
-rw-r--r--kmicromail/libetpan/nntp/newsnntp.c2486
-rw-r--r--kmicromail/libetpan/nntp/newsnntp.h188
-rw-r--r--kmicromail/libetpan/nntp/newsnntp_socket.c74
-rw-r--r--kmicromail/libetpan/nntp/newsnntp_socket.h55
-rw-r--r--kmicromail/libetpan/nntp/newsnntp_ssl.c73
-rw-r--r--kmicromail/libetpan/nntp/newsnntp_ssl.h55
-rw-r--r--kmicromail/libetpan/nntp/newsnntp_types.h144
-rw-r--r--kmicromail/libetpan/pop3/.libs/libmailpop3.abin0 -> 48834 bytes
-rw-r--r--kmicromail/libetpan/pop3/mailpop3.c1230
-rw-r--r--kmicromail/libetpan/pop3/mailpop3.h100
-rw-r--r--kmicromail/libetpan/pop3/mailpop3_helper.c78
-rw-r--r--kmicromail/libetpan/pop3/mailpop3_helper.h64
-rw-r--r--kmicromail/libetpan/pop3/mailpop3_socket.c73
-rw-r--r--kmicromail/libetpan/pop3/mailpop3_socket.h54
-rw-r--r--kmicromail/libetpan/pop3/mailpop3_ssl.c73
-rw-r--r--kmicromail/libetpan/pop3/mailpop3_ssl.h54
-rw-r--r--kmicromail/libetpan/pop3/mailpop3_types.h107
-rw-r--r--kmicromail/libetpan/smtp/.libs/libmailsmtp.abin0 -> 49200 bytes
-rw-r--r--kmicromail/libetpan/smtp/TODO1
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp.c982
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp.h94
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp_helper.c232
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp_helper.h74
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp_socket.c99
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp_socket.h56
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp_ssl.c74
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp_ssl.h55
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp_types.h126
-rw-r--r--kmicromail/libetpan/tests/README58
-rw-r--r--kmicromail/libetpan/tests/compose-msg.c317
-rw-r--r--kmicromail/libetpan/tests/fetch-attachment.c274
-rw-r--r--kmicromail/libetpan/tests/frm-common.c158
-rw-r--r--kmicromail/libetpan/tests/frm-common.h14
-rw-r--r--kmicromail/libetpan/tests/frm-simple.c227
-rw-r--r--kmicromail/libetpan/tests/frm-tree.c234
-rw-r--r--kmicromail/libetpan/tests/frm.c158
-rw-r--r--kmicromail/libetpan/tests/option-parser.c234
-rw-r--r--kmicromail/libetpan/tests/option-parser.h28
-rw-r--r--kmicromail/libetpan/tests/readmsg-common.c720
-rw-r--r--kmicromail/libetpan/tests/readmsg-common.h34
-rw-r--r--kmicromail/libetpan/tests/readmsg-simple.c133
-rw-r--r--kmicromail/libetpan/tests/readmsg.c355
-rw-r--r--kmicromail/libetpan/tests/smtpsend.c278
-rw-r--r--kmicromail/libetpan/tools/.libs/libtools.abin0 -> 187742 bytes
-rw-r--r--kmicromail/libetpan/tools/base64.c143
-rw-r--r--kmicromail/libetpan/tools/base64.h59
-rw-r--r--kmicromail/libetpan/tools/carray.c143
-rw-r--r--kmicromail/libetpan/tools/carray.h124
-rw-r--r--kmicromail/libetpan/tools/charconv.c251
-rw-r--r--kmicromail/libetpan/tools/charconv.h67
-rw-r--r--kmicromail/libetpan/tools/chash.c395
-rw-r--r--kmicromail/libetpan/tools/chash.h166
-rw-r--r--kmicromail/libetpan/tools/cinthash.c248
-rw-r--r--kmicromail/libetpan/tools/cinthash.h69
-rw-r--r--kmicromail/libetpan/tools/clist.c266
-rw-r--r--kmicromail/libetpan/tools/clist.h134
-rw-r--r--kmicromail/libetpan/tools/connect.c86
-rw-r--r--kmicromail/libetpan/tools/connect.h54
-rw-r--r--kmicromail/libetpan/tools/hmac-md5.h94
-rw-r--r--kmicromail/libetpan/tools/mail.h56
-rw-r--r--kmicromail/libetpan/tools/mail_cache_db.c364
-rw-r--r--kmicromail/libetpan/tools/mail_cache_db.h138
-rw-r--r--kmicromail/libetpan/tools/mail_cache_db_types.h52
-rw-r--r--kmicromail/libetpan/tools/maillock.c286
-rw-r--r--kmicromail/libetpan/tools/maillock.h53
-rw-r--r--kmicromail/libetpan/tools/mailstream.c394
-rw-r--r--kmicromail/libetpan/tools/mailstream.h73
-rw-r--r--kmicromail/libetpan/tools/mailstream_helper.c383
-rw-r--r--kmicromail/libetpan/tools/mailstream_helper.h70
-rw-r--r--kmicromail/libetpan/tools/mailstream_low.c90
-rw-r--r--kmicromail/libetpan/tools/mailstream_low.h62
-rw-r--r--kmicromail/libetpan/tools/mailstream_socket.c239
-rw-r--r--kmicromail/libetpan/tools/mailstream_socket.h61
-rw-r--r--kmicromail/libetpan/tools/mailstream_ssl.c312
-rw-r--r--kmicromail/libetpan/tools/mailstream_ssl.h59
-rw-r--r--kmicromail/libetpan/tools/mailstream_types.h87
-rw-r--r--kmicromail/libetpan/tools/mapping.c67
-rw-r--r--kmicromail/libetpan/tools/mapping.h54
-rw-r--r--kmicromail/libetpan/tools/md5.c570
-rw-r--r--kmicromail/libetpan/tools/md5.h88
-rw-r--r--kmicromail/libetpan/tools/md5global.h79
-rw-r--r--kmicromail/libetpan/tools/mmapstring.c526
-rw-r--r--kmicromail/libetpan/tools/mmapstring.h136
376 files changed, 139862 insertions, 0 deletions
diff --git a/kmicromail/libetpan/config.h b/kmicromail/libetpan/config.h
new file mode 100644
index 0000000..b7583bb
--- a/dev/null
+++ b/kmicromail/libetpan/config.h
@@ -0,0 +1,112 @@
1/* config.h. Generated by configure. */
2/* config.h.in. Generated from configure.in by autoheader. */
3/* Define if you want to use OpenSSL. */
4#define USE_SSL 1
5
6/* Define this to allow lazy syntax checking */
7#define UNSTRICT_SYNTAX 1
8
9/* Define to the version number */
10/* #undef VERSION */
11
12/* Define to detected Berkeley DB major version number */
13#define DBVERS 0
14
15/* Define to 1 if you have the <ctype.h> header file. */
16#define HAVE_CTYPE_H 1
17
18/* Define to 1 if you have the <dlfcn.h> header file. */
19#define HAVE_DLFCN_H 1
20
21/* Define to 1 if you have the <fcntl.h> header file. */
22#define HAVE_FCNTL_H 1
23
24/* Define to 1 if you have the `getpagesize' function. */
25#define HAVE_GETPAGESIZE 1
26
27/* Define if you have the iconv() function. */
28#define HAVE_ICONV 1
29
30/* Define to 1 if you have the <inttypes.h> header file. */
31#define HAVE_INTTYPES_H 1
32
33/* Define to 1 if you have the `nsl' library (-lnsl). */
34/* #undef HAVE_LIBNSL */
35
36/* Define to 1 if you have the `socket' library (-lsocket). */
37/* #undef HAVE_LIBSOCKET */
38
39/* Define to 1 if you have the <limits.h> header file. */
40#define HAVE_LIMITS_H 1
41
42/* Define to 1 if you have the <memory.h> header file. */
43#define HAVE_MEMORY_H 1
44
45/* Define to 1 if you have a working `mmap' system call. */
46#define HAVE_MMAP 1
47
48/* Define to 1 if you have the <netdb.h> header file. */
49#define HAVE_NETDB_H 1
50
51/* Define to 1 if you have the <netinet/in.h> header file. */
52#define HAVE_NETINET_IN_H 1
53
54/* Define to 1 if you have the <stdint.h> header file. */
55#define HAVE_STDINT_H 1
56
57/* Define to 1 if you have the <stdlib.h> header file. */
58#define HAVE_STDLIB_H 1
59
60/* Define to 1 if you have the <strings.h> header file. */
61#define HAVE_STRINGS_H 1
62
63/* Define to 1 if you have the <string.h> header file. */
64#define HAVE_STRING_H 1
65
66/* Define to 1 if you have the <sys/mman.h> header file. */
67#define HAVE_SYS_MMAN_H 1
68
69/* Define to 1 if you have the <sys/param.h> header file. */
70#define HAVE_SYS_PARAM_H 1
71
72/* Define to 1 if you have the <sys/socket.h> header file. */
73#define HAVE_SYS_SOCKET_H 1
74
75/* Define to 1 if you have the <sys/stat.h> header file. */
76#define HAVE_SYS_STAT_H 1
77
78/* Define to 1 if you have the <sys/types.h> header file. */
79#define HAVE_SYS_TYPES_H 1
80
81/* Define to 1 if you have the <unistd.h> header file. */
82#define HAVE_UNISTD_H 1
83
84/* Define as const if the declaration of iconv() needs const. */
85#define ICONV_CONST
86
87/* Define this to the version of libEtPan */
88#define LIBETPAN_VERSION "0.32"
89
90/* Define this to the major version of libEtPan */
91#define LIBETPAN_VERSION_MAJOR 0
92
93/* Define this to the minor version of libEtPan */
94#define LIBETPAN_VERSION_MINOR 32
95
96/* Define to the address where bug reports for this package should be sent. */
97#define PACKAGE_BUGREPORT ""
98
99/* Define to the full name of this package. */
100#define PACKAGE_NAME ""
101
102/* Define to the full name and version of this package. */
103#define PACKAGE_STRING ""
104
105/* Define to the one symbol short name of this package. */
106#define PACKAGE_TARNAME ""
107
108/* Define to the version of this package. */
109#define PACKAGE_VERSION ""
110
111/* Define to 1 if you have the ANSI C header files. */
112#define STDC_HEADERS 1
diff --git a/kmicromail/libetpan/doc/API.sgml b/kmicromail/libetpan/doc/API.sgml
new file mode 100644
index 0000000..4516979
--- a/dev/null
+++ b/kmicromail/libetpan/doc/API.sgml
@@ -0,0 +1,15097 @@
1<!doctype book PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
2
3<book id="libetpan-api">
4 <bookinfo>
5 <date>2003-12-03</date>
6 <title>libEtPan! API</title>
7 <authorgroup>
8 <author>
9 <firstname>Viet Hoa</firstname>
10 <surname>DINH</surname>
11 </author>
12 </authorgroup>
13 <copyright>
14 <year>2003</year>
15 <holder>DINH Viet Hoa</holder>
16 </copyright>
17 </bookinfo>
18 <toc></toc>
19
20 <!-- Introduction -->
21 <chapter>
22 <title>Introduction</title>
23 <para>
24 This document will describe the API of libEtPan!
25 </para>
26 </chapter>
27
28 <!-- Tools -->
29 <chapter>
30 <title>Tools and datatypes</title>
31
32 <para>
33 libEtPan! include a collection of datatypes such as lists,
34 arrays, hash tables and tools such as buffered I/O.
35 </para>
36
37 <!-- Array -->
38 <sect1>
39 <title>Array</title>
40
41 <programlisting role="C">
42#include &lt;libetpan/libetpan.h&gt;
43
44typedef struct carray_s carray;
45 </programlisting>
46
47 <para>
48 <command>carray</command> is an array of pointers that will
49 resize automatically in case a new element is added.
50 </para>
51
52 <para>
53 The <command>carray</command> is implemented with an array
54 <command>(void **)</command> that can be resized. An array has a
55 size: this is the number of elements that can be added before
56 the table is resized. It also has a count of elements: this is
57 the elements that exist in the array.
58 </para>
59
60 <sect2 id="carray-new">
61 <title>carray_new and carray_free</title>
62
63 <programlisting role="C">
64carray * carray_new(unsigned int initsize);
65
66void carray_free(carray * array);
67 </programlisting>
68
69 <para>
70 <command>carray_new()</command> creates a new array with an
71 initial size. The array is not resized until the number of
72 element reach the initial size. It returns
73 <command>NULL</command> in case of failure.
74 </para>
75
76 <para>
77 <command>carray_free()</command> releases memory used by the
78 given array.
79 </para>
80
81 <example>
82 <title>carray creation</title>
83 <programlisting role="C">
84#include &lt;libetpan/libetpan.h&gt;
85#include &lt;stdlib.h&gt;
86
87#define SIZE 50
88
89int main(void)
90{
91 carray * a;
92
93 a = carray_new(SIZE);
94 if (a == NULL)
95 exit(EXIT_FAILURE);
96
97 /* do things here */
98
99 carray_free(a);
100
101 exit(EXIT_SUCESS);
102}
103 </programlisting>
104 </example>
105 </sect2>
106
107 <sect2 id="carray-set-size">
108 <title>carray_set_size</title>
109
110 <programlisting role="C">
111int carray_set_size(carray * array, uint32_t new_size);
112 </programlisting>
113
114 <para>
115 <command>carray_set_size()</command> sets the size of the
116 array. It returns <command>0</command> in case of success,
117 <command>-1</command> in case of failure.
118 </para>
119
120 <example>
121 <title>preallocating carray</title>
122 <programlisting role="C">
123#include &lt;libetpan/libetpan.h&gt;
124#include &lt;stdlib.h&gt;
125
126#define SIZE 50
127#define NEWSIZE 200
128
129int main(void)
130{
131 carray * a;
132 unsigned int i;
133 char p[500];
134
135 a = carray_new(SIZE);
136 if (a == NULL)
137 goto err;
138
139 r = carray_set_size(NEWSIZE);
140 if (r &lt; 0)
141 goto free;
142
143 for(i = 0 ; i &lt; NEWSIZE ; i ++)
144 carray_set(a, i, &amp;p[i]);
145
146 /* do things here */
147
148 carray_free(a);
149
150 exit(EXIT_SUCESS);
151
152 free:
153 carray_free(a);
154 err:
155 exit(EXIT_FAILURE);
156}
157 </programlisting>
158 </example>
159 </sect2>
160
161 <!-- carray_count, carray_add, carray_get and carray_set -->
162 <sect2 id="carray-count">
163 <title>carray_count, carray_add, carray_get and carray_set</title>
164
165 <programlisting role="C">
166int carray_count(carray);
167
168int carray_add(carray * array, void * data, unsigned int * index);
169
170void * carray_get(carray * array, unsigned int indx);
171
172void carray_set(carray * array, unsigned int indx, void * value);
173 </programlisting>
174
175 <para>
176 <command>carray_count()</command> returns the number of
177 elements in the <command>carray</command>.
178 Complexity is O(1).
179 </para>
180
181 <para>
182 <command>carray_add()</command>adds an element at the end of
183 the array. The <command>index</command> of the element is
184 returns in <command>(* index)</command> if
185 <command>index</command> is not <command>NULL</command>. It
186 returns <command>0</command> in case of success,
187 <command>-1</command> in case of failure.
188 Complexity is O(1).
189 </para>
190
191 <para>
192 <command>carray_get()</command> returns the elements contained
193 at the given cell of the table.
194 Complexity is O(1).
195 </para>
196
197 <para>
198 <command>carray_set()</command> replace the element at the
199 given index of table table with the given value.
200 Complexity is O(1).
201 </para>
202
203 <example>
204 <title>carray access</title>
205 <programlisting role="C">
206#include &lt;libetpan/libetpan.h&gt;
207#include &lt;string.h&gt;
208
209#define SIZE 50
210
211int main(void)
212{
213 carray * a;
214 int r;
215
216 a = carray_new(SIZE);
217 if (a == NULL)
218 goto err;
219
220 r = carray_add(a, "foo-bar-1", NULL);
221 if (r &lt; 0)
222 goto free;
223
224 carray_add(a, "foo-bar-2", NULL);
225 if (r &lt; 0)
226 goto free;
227
228 carray_add(a, "foo-bar-3", NULL);
229 if (r &lt; 0)
230 goto free;
231
232 for(i = 0 ; i &lt; carray_count(a) ; i ++) {
233 char * str;
234
235 str = carray_get(a, i);
236 if (strcmp("foo-bar-2", str) == 0)
237 carray_set(a, i, "foo-bar-2-replacement");
238
239 printf("%s\n", str);
240 }
241
242 carray_free(a);
243
244 exit(EXIT_SUCESS);
245
246 free:
247 carray_free(a);
248 err:
249 exit(EXIT_FAILURE);
250}
251 </programlisting>
252 </example>
253
254 </sect2>
255
256 <!-- carray_delete -->
257 <sect2 id="carray-delete">
258 <title>carray_delete</title>
259
260 <programlisting role="C">
261int carray_delete(carray * array, uint32_t indx);
262
263int carray_delete_slow(carray * array, uint32_t indx);
264
265int carray_delete_fast(carray * array, uint32_t indx);
266 </programlisting>
267
268 <para>
269 <command>carray_delete()</command> removes an element of the
270 table. Order will not be garanteed. The returned result can
271 be ignored.
272 Complexity is O(1).
273 </para>
274
275 <para>
276 <command>carray_delete_slow()</command> removes an element of
277 the table. Order will be garanteed. The returned result can
278 be ignored.
279 Complexity is O(n).
280 </para>
281
282 <para>
283 <command>carray_delete_fast()</command> the element will just
284 be replaced with <command>NULL</command>. Order will be kept
285 but the number of elements will remains the same. The
286 returned result can be ignored.
287 Complexity is O(1).
288 </para>
289
290 <example>
291 <title>deletion in carray</title>
292 <programlisting role="C">
293#include &lt;libetpan/libetpan.h&gt;
294
295#define SIZE 50
296
297carray * build_array(void)
298{
299 carray * a;
300
301 a = carray_new(SIZE);
302 if (a == NULL)
303 goto err;
304
305 r = carray_add(a, "foo-bar-1", NULL);
306 if (r &lt; 0)
307 goto free;
308
309 carray_add(a, "foo-bar-2", NULL);
310 if (r &lt; 0)
311 goto free;
312
313 carray_add(a, "foo-bar-3", NULL);
314 if (r &lt; 0)
315 goto free;
316
317 return a;
318
319 free:
320 carray_free(a);
321 err:
322 exit(EXIT_FAILURE);
323}
324
325void delete(carray * a)
326{
327 /* deleting foo-bar-1 */
328 carray_delete(a, 0);
329 /* resulting size is 2, order of elements is undefined */
330}
331
332void delete_slow(carray * a)
333{
334 /* deleting foo-bar-1 */
335 carray_delete_slow(a, 0);
336 /* resulting size is 2, order of elements is the same */
337}
338
339void delete_fast(carray * a)
340{
341 /* deleting foo-bar-1 */
342 carray_delete_slow(a, 0);
343 /*
344 resulting size is 3,
345 order of elements is { NULL, foo-bar-2, foo-bar-3 }
346 */
347}
348 </programlisting>
349 </example>
350 </sect2>
351
352 <!-- carray_data -->
353 <sect2 id="carray-data">
354 <title>carray_data</title>
355
356 <programlisting role="C">
357void ** carray_data(carray);
358 </programlisting>
359
360 <para>
361 <command>carray_data</command>returns the table used for
362 implementation :
363 <command>(void **)</command>.
364 </para>
365
366 </sect2>
367
368
369 </sect1>
370
371 <!-- List -->
372 <sect1 id="clist">
373 <title>List</title>
374
375 <programlisting role="C">
376#include &lt;libetpan/libetpan.h&gt;
377
378typedef struct clist_s clist;
379
380typedef clistcell clistiter;
381 </programlisting>
382
383 <para>
384 <command>clist()</command> is a list of cells.
385 Each cell of the list contains one element. This element is a
386 pointer. An iterator (<command>clistiter</command>) is a
387 pointer to an element of the list. With an iterator, we can
388 get the previous element of the list, the next element of the
389 list and the content of the element.
390 </para>
391
392 <sect2 id="clist-new">
393 <title>clist_new and clist_free</title>
394
395 <programlisting role="C">
396clist * clist_new(void);
397
398void clist_free(clist *);
399 </programlisting>
400
401 <para>
402 <command>clist_new()</command> allocates a new empty list and
403 returns it.
404 </para>
405
406 <para>
407 <command>clist_free()</command> frees the entire list with
408 its cells.
409 </para>
410
411 <example>
412 <title>clist creation</title>
413 <programlisting role="C">
414#include &lt;libetpan/libetpan.h&gt;
415
416int main(void)
417{
418 clist * list;
419
420 list = clist_new();
421 if (list == NULL)
422 goto err;
423
424 r = clist_append(list, "foo-bar");
425 if (r &lt; 0)
426
427 clist_free(list);
428
429 exit(EXIT_SUCCESS);
430
431 free:
432 clist_free(list);
433 err:
434 exit(EXIT_FAILURE);
435}
436 </programlisting>
437 </example>
438 </sect2>
439
440 <sect2 id="clist-count">
441 <title>clist_isempty and clist_count</title>
442
443 <programlisting role="C">
444int clist_isempty(clist *);
445
446int clist_count(clist *);
447 </programlisting>
448
449 <para>
450 <command>clist_isempty()</command> returns 1 if the list is
451 empty, else it is 0.
452 Complexity is O(1).
453 </para>
454
455 <para>
456 <command>clist_count()</command> returns the number of
457 elements in the list.
458 Complexity is O(1).
459 </para>
460 </sect2>
461
462 <sect2 id="clist-begin">
463 <title>running through clist</title>
464
465 <programlisting role="C">
466clistiter * clist_begin(clist *);
467
468clistiter * clist_end(clist *);
469
470clistiter * clist_next(clistiter *);
471
472clistiter * clist_previous(clistiter *);
473
474void * clist_content(clistiter *);
475
476void * clist_nth_data(clist * lst, int index);
477
478clistiter * clist_nth(clist * lst, int index);
479 </programlisting>
480
481 <para>
482 <command>clist_begin()</command> returns an iterator to the
483 first element of the list.
484 Complexity is O(1).
485 </para>
486
487 <para>
488 <command>clist_end()</command> returns an iterator to the last
489 element of the list.
490 Complexity is O(1).
491 </para>
492
493 <para>
494 <command>clist_next()</command> returns an iterator to the
495 next element of the list.
496 Complexity is O(1).
497 </para>
498
499 <para>
500 <command>clist_previous()</command> returns an iterator to the
501 previous element of the list.
502 Complexity is O(1).
503 </para>
504
505 <para>
506 <command>clist_content()</command> returns the element
507 contained in the cell pointed by the iterator in the list.
508 Complexity is O(1).
509 </para>
510
511 <para>
512 <command>clist_nth()</command> returns an iterator on the
513 <command>index</command>-th element of the list.
514 Complexity is O(n).
515 </para>
516
517 <para>
518 <command>clist_nth_data()</command> returns the index-th
519 element of the list.
520 Complexity is O(n).
521 </para>
522
523 <example>
524 <title>displaying content of clist</title>
525 <programlisting role="C">
526#include &lt;libetpan/libetpan.h&gt;
527
528int main(void)
529{
530 clist * list;
531 clistiter * iter;
532
533 list = build_string_list();
534 if (list == NULL)
535 goto err;
536
537 for(iter = clist_begin(list) ; iter != NULL ; iter =
538 clist_next(iter)) {
539 char * str;
540
541 str = clist_content(iter);
542 printf("%s\n", str);
543 }
544
545 clist_free(list);
546
547 exit(EXIT_SUCCESS);
548
549 free:
550 clist_free(list);
551 err:
552 exit(EXIT_FAILURE);
553}
554 </programlisting>
555 </example>
556 </sect2>
557
558
559 <sect2 id="clist-append">
560 <title>clist modification</title>
561
562 <programlisting role="C">
563int clist_prepend(clist *, void *);
564
565int clist_append(clist *, void *);
566
567int clist_insert_before(clist *, clistiter *, void *);
568
569int clist_insert_after(clist *, clistiter *, void *);
570
571clistiter * clist_delete(clist *, clistiter *);
572 </programlisting>
573
574 <para>
575 <command>clist_prepend()</command> adds an element at the
576 beginning of the list. Returns 0 on sucess, -1 on error.
577 Complexity is O(1).
578 </para>
579
580 <para>
581 <command>clist_append()</command> adds an element at the end
582 of the list. Returns 0 on sucess, -1 on error.
583 Complexity is O(1).
584 </para>
585
586 <para>
587 <command>clist_insert_before()</command> adds an element
588 before the element pointed by the given iterator in the
589 list. Returns 0 on sucess, -1 on error.
590 Complexity is O(1).
591 </para>
592
593 <para>
594 <command>clist_insert_after()</command> adds an element after
595 the element pointed by the given iterator in the list.
596 Returns 0 on sucess, -1 on error.
597 Complexity is O(1).
598 </para>
599
600 <para>
601 <command>clist_delete()</command> the elements pointed by
602 the given iterator in the list and returns an iterator to
603 the next element of the list.
604 Complexity is O(1).
605 </para>
606
607 <example>
608 <title>deleting elements in a clist</title>
609 <programlisting role="C">
610#include &lt;libetpan/libetpan.h&gt;
611
612voir print_content(void * content, void * user_data)
613{
614 char * str;
615
616 str = content;
617
618 printf("%s\n", str);
619}
620
621int main(void)
622{
623 clist * list;
624 clistiter * iter;
625
626 list = build_string_list();
627 if (list == NULL)
628 goto err;
629
630 iter = = clist_begin(list);
631 while (iter != NULL)
632 char * str;
633
634 str = clist_content(iter);
635 if (strcmp(str, "foo-bar") == 0)
636 iter = clist_delete(list, cur);
637 else
638 iter = clist_next(iter);
639 }
640
641 clist_foreach(list, print_content, NULL);
642 printf("\n");
643
644 clist_free(list);
645
646 exit(EXIT_SUCCESS);
647
648 free:
649 clist_free(list);
650 err:
651 exit(EXIT_FAILURE);
652}
653 </programlisting>
654 </example>
655 </sect2>
656
657 <sect2 id="clist-foreach">
658 <title>clist_foreach</title>
659
660 <programlisting role="C">
661typedef void (* clist_func)(void *, void *);
662
663void clist_foreach(clist * lst, clist_func func, void * data);
664 </programlisting>
665
666 <para>
667 <command>clist_foreach()</command> apply a fonction to each
668 element of the list.
669 Complexity is O(n).
670 </para>
671 </sect2>
672
673 <sect2 id="clist-concat">
674 <title>clist_concat</title>
675
676 <programlisting role="C">
677void clist_concat(clist * dest, clist * src);
678 </programlisting>
679
680 <para>
681 <command>clist_concat()</command> adds all the elements of src
682 at the end of dest. Elements are added in the same
683 order. src is an empty list when the operation is finished.
684 Complexity is O(1).
685 </para>
686
687 <example>
688 <title>merging two clists</title>
689 <programlisting role="C">
690#include &lt;libetpan/libetpan.h&gt;
691
692int main(void)
693{
694 clist * list;
695 clist * list_2;
696 clistiter * iter;
697
698 list = build_string_list();
699 if (list == NULL)
700 goto err;
701
702 list_2 = build_string_list_2();
703 if (list == NULL)
704 goto free_list;
705
706 clist_concat(list, list_2);
707 clist_free(list_2);
708
709 for(iter = clist_begin(list) ; iter != NULL ; iter =
710 clist_next(iter)) {
711 char * str;
712
713 str = clist_content(iter);
714 printf("%s\n", str);
715 }
716
717 clist_free(list);
718
719 exit(EXIT_SUCCESS);
720
721 free_list:
722 clist_free(list);
723 err:
724 exit(EXIT_FAILURE);
725}
726 </programlisting>
727 </example>
728
729 </sect2>
730 </sect1>
731
732 <!-- Hash -->
733 <sect1>
734 <title>Hash table</title>
735
736 <programlisting role="C">
737#include &lt;libetpan/libetpan.h&gt;
738
739typedef struct chash chash;
740
741typedef struct chashcell chashiter;
742
743typedef struct {
744 char * data;
745 int len;
746} chashdatum;
747 </programlisting>
748
749 <para>
750 <command>chash</command> is a hash table.
751 <command>chashiter</command> is a pointer to an element of the
752 hash table.
753 <command>chashdatum</command> is an element to be placed in
754 the hash table as a key or a value. It consists in
755 data and a corresponding length.
756 </para>
757
758 <sect2 id="chash-new">
759 <title>chash_new and chash_free</title>
760 <programlisting role="C">
761#define CHASH_COPYNONE 0
762#define CHASH_COPYKEY 1
763#define CHASH_COPYVALUE 2
764#define CHASH_COPYALL (CHASH_COPYKEY | CHASH_COPYVALUE)
765
766chash * chash_new(int size, int flags);
767
768void chash_free(chash * hash);
769 </programlisting>
770
771 <para>
772 <command>chash_new()</command> returns a new empty hash table
773 or <command>NULL</command> if this
774 failed. <command>size</command> is the initial size of the
775 table used for implementation. <command>flags</command> can
776 be a combinaison of <command>CHASH_COPYKEY</command> and
777 <command>CHASH_COPYVALUE</command>.
778 <command>CHASH_COPYKEY</command> enables copy of key, so
779 that the initial value used for <command>chash_set()</command>
780 </para>
781
782 <para>
783 <command>chash_free()</command> releases memory used by the
784 hash table.
785 </para>
786 </sect2>
787
788 <sect2 id="chash-get">
789 <title>chash_set and chash_get</title>
790 <programlisting role="C">
791int chash_set(chash * hash,
792 chashdatum * key, chashdatum * value, chashdatum * oldvalue);
793
794int chash_get(chash * hash,
795 chashdatum * key, chashdatum * result);
796 </programlisting>
797
798 <para>
799 <command>chash_set()</command> adds a new element into the
800 hash table. If a previous element had the same key, it is
801 returns into oldvalue if <command>oldvalue</command> is
802 different of NULL.
803 Medium complexity is O(1).
804 </para>
805
806 <para>
807 returns -1 if it fails, 0 on success.
808 </para>
809
810 <para>
811 <command>chash_get()</command>returns the corresponding value
812 of the given key. If there is no corresponding value, -1 is
813 returned. 0 on success.
814 Medium complexity is O(1).
815 </para>
816
817 <example>
818 <title>chash insert and lookup</title>
819 <programlisting role="C">
820int main(void)
821{
822 chash * hash;
823 int r;
824 chashdatum key;
825 chashdatum value;
826 char * str1 = "my-data";
827 char * str2 = "my-data";
828
829 hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYNONE);
830
831 key.data = "foo";
832 key.len = strlen("foo");
833 value.data = str1;
834 value.data = strlen(str1) + 1;
835 /* + 1 is needed to get the terminal zero in the returned string */
836 r = chash_set(hash, &amp;key, &amp;value, NULL);
837 if (r &lt; 0)
838 goto free_hash;
839
840 key.data = "bar";
841 key.len = strlen("bar");
842 value.data = str2;
843 value.data = strlen(str2) + 1;
844 if (r &lt; 0)
845 goto free_hash;
846
847 key.data = "foo";
848 key.len = strlen("foo");
849 r = chash_get(hash, &amp;key, &amp;value);
850 if (r &lt; 0) {
851 printf("element not found\n");
852 }
853 else {
854 char * str;
855
856 str = value.data;
857 printf("found : %s", str);
858 }
859
860 chash_free(hash);
861
862 exit(EXIT_SUCCESS);
863
864 free_hash:
865 chash_free(hash);
866 err:
867 exit(EXIT_FAILURE);
868}
869 </programlisting>
870 </example>
871 </sect2>
872
873 <sect2 id="chash-delete">
874 <title>chash_delete</title>
875 <programlisting role="C">
876int chash_delete(chash * hash,
877 chashdatum * key, chashdatum * oldvalue);
878 </programlisting>
879
880 <para>
881 deletes the key/value pair given the corresponding key.
882 The value is returned in old_value.
883 If there is no corresponding value, -1 is returned. 0 on success.
884 Medium complexity is O(1).
885 </para>
886
887 <example>
888 <title>key deletion in a chash</title>
889 <programlisting role="C">
890int main(void)
891{
892 chash * hash;
893 int r;
894 chashdatum key;
895 chashdatum value;
896 char * str1 = "my-data";
897 char * str2 = "my-data";
898
899 hash = build_hash();
900
901 key.data = "foo";
902 key.len = strlen("foo");
903 chash_delete(hash, &amp;key, &amp;value);
904
905 /* it will never be possible to lookup "foo" */
906 key.data = "foo";
907 key.len = strlen("foo");
908 r = chash_get(hash, &amp;key, &amp;value);
909 if (r &lt; 0) {
910 printf("element not found\n");
911 }
912 else {
913 char * str;
914
915 str = value.data;
916 printf("found : %s", str);
917 }
918
919 chash_free(hash);
920
921 exit(EXIT_SUCCESS);
922
923 free_hash:
924 chash_free(hash);
925 err:
926 exit(EXIT_FAILURE);
927}
928 </programlisting>
929 </example>
930 </sect2>
931
932 <sect2 id="chash-resize">
933 <title>chash_resize</title>
934 <programlisting role="C">
935int chash_resize(chash * hash, int size);
936 </programlisting>
937
938 <para>
939 <command>chash_resize()</command> changes the size of the
940 table used for implementation of the hash table.
941 returns 0 on success, -1 on failure.
942 </para>
943 </sect2>
944
945 <sect2 id="chash-begin">
946 <title>running through the chash</title>
947 <programlisting role="C">
948chashiter * chash_begin(chash * hash);
949
950chashiter * chash_next(chash * hash, chashiter * iter);
951
952void chash_key(chashiter * iter, chashdatum * result);
953
954void chash_value(chashiter iter, chashdatum * result);
955 </programlisting>
956
957 <para>
958 <command>chash_begin()</command> returns a pointer to the
959 first element of the hash table. Returns
960 <command>NULL</command> if there is no elements in the hash
961 table.
962 Complexity is O(n).
963 </para>
964
965 <para>
966 <command>chash_next()</command> returns a pointer to the next
967 element of the hash table. Returns <command>NULL</command>
968 if there is no next element.
969 Complexity is O(n) but n calls to chash_next() also has
970 a complexity of O(n).
971 </para>
972
973 <para>
974 <command>chash_key()</command> returns the key of the given
975 element of the hash table.
976 </para>
977
978 <para>
979 <command>chash_value</command> returns the value of the
980 given element of the hash table.
981 </para>
982
983 <example>
984 <title>running through a chash</title>
985 <programlisting role="C">
986int main(void)
987{
988 chash * hash;
989 int r;
990 chashiter * iter;
991
992 hash = build_hash();
993
994 /* this will display all the values stored in the hash */
995 for(iter = chash_begin(hash) ; iter != NULL ; iter =
996 chash_next(hash, iter)) {
997 chashdatum key;
998 chashdatum value;
999 char * str;
1000
1001 chash_value(iter, &amp;value);
1002 str = value.data;
1003 printf("%s\n", str);
1004 }
1005
1006 chash_free(hash);
1007}
1008 </programlisting>
1009 </example>
1010 </sect2>
1011
1012 <sect2 id="chash-count">
1013 <title>chash_size and chash_count</title>
1014 <programlisting role="C">
1015int chash_size(chash * hash);
1016
1017int chash_count(chash * hash);
1018 </programlisting>
1019
1020 <para>
1021 <command>chash_size()</command> returns the size of the table
1022 used for implementation of the hash table.
1023 Complexity is O(1).
1024 </para>
1025
1026 <para>
1027 <command>chash_count()</command> returns the number of
1028 elements in the hash table.
1029 Complexity is O(1).
1030 </para>
1031 </sect2>
1032 </sect1>
1033
1034 <!-- mailstream -->
1035 <sect1>
1036 <title>Buffered I/O</title>
1037
1038<programlisting role="C">
1039#include &lt;libetpan/libetpan.h&gt;
1040
1041typedef struct _mailstream mailstream;
1042 </programlisting>
1043
1044 <para>
1045 streams are objects where we can read data from and write data
1046 to. They are not seekable. That can be for example a pipe or a
1047 network stream.
1048 </para>
1049
1050 <programlisting role="C">
1051mailstream * mailstream_new(mailstream_low * low, size_t buffer_size);
1052
1053int mailstream_close(mailstream * s);
1054 </programlisting>
1055
1056 <para>
1057 <command>mailstream_new()</command> creates a new stream
1058 stream with the low-level (see <xref linkend="mailstream-low">)
1059 stream and a given buffer size.
1060 </para>
1061
1062 <para>
1063 <command>mailstream_close()</command> closes the stream.
1064 This function will be in charge to free the
1065 <command>mailstream_low</command> structure.
1066 </para>
1067
1068
1069 <programlisting role="C">
1070ssize_t mailstream_write(mailstream * s, void * buf, size_t count);
1071
1072int mailstream_flush(mailstream * s);
1073
1074ssize_t mailstream_read(mailstream * s, void * buf, size_t count);
1075
1076ssize_t mailstream_feed_read_buffer(mailstream * s);
1077 </programlisting>
1078
1079 <para>
1080 <command>mailstream_write()</command> writes a buffer to the
1081 given stream. This write operation will be buffered.
1082 </para>
1083
1084 <para>
1085 <command>mailstream_flush()</command> will force a write of
1086 all buffered data for a given stream.
1087 </para>
1088
1089 <para>
1090 <command>mailstream_read()</command> reads data from the
1091 stream to the given buffer.
1092 </para>
1093
1094 <para>
1095 <command>mailstream_feed_read_buffer()</command> this function
1096 will just fill the buffer for reading.
1097 </para>
1098
1099 <programlisting role="C">
1100mailstream_low * mailstream_get_low(mailstream * s);
1101
1102void mailstream_set_low(mailstream * s, mailstream_low * low);
1103 </programlisting>
1104
1105 <para>
1106 <command>mailstream_get_low()</command> returns the low-level
1107 stream of the given stream.
1108 </para>
1109
1110 <para>
1111 <command>mailstream_set_low()</command> changes the low-level
1112 of the given stream. Useful, for
1113 example, when a stream change from clear stream to SSL
1114 stream.
1115 </para>
1116
1117 <programlisting role="C">
1118char * mailstream_read_line(mailstream * stream, MMAPString * line);
1119
1120char * mailstream_read_line_append(mailstream * stream, MMAPString * line);
1121
1122char * mailstream_read_line_remove_eol(mailstream * stream, MMAPString * line);
1123
1124char * mailstream_read_multiline(mailstream * s, size_t size,
1125 MMAPString * stream_buffer,
1126 MMAPString * multiline_buffer,
1127 size_t progr_rate,
1128 progress_function * progr_fun);
1129 </programlisting>
1130
1131 <para>
1132 <command>mailstream_read_line()</command> reads an entire line
1133 from the buffer and store it into the
1134 given string. returns <command>NULL</command> on error, the
1135 corresponding array
1136 of <command>char</command> is returned otherwise.
1137 </para>
1138
1139 <para>
1140 <command>mailstream_read_line_append()</command> reads an entire
1141 line from the buffer and appends it to the
1142 given string. returns <command>NULL</command> on error, the
1143 array of char corresponding to the entire buffer is returned
1144 otherwise.
1145 </para>
1146
1147 <para>
1148 <command>mailstream_read_line_remove_eol()</command> reads an
1149 entire line from the buffer and store it into the
1150 given string. All CR LF are removed.
1151 returns <command>NULL</command> on error, the corresponding
1152 array of <command>char</command> is returned otherwise.
1153 </para>
1154
1155 <para>
1156 <command>mailstream_read_multiline()</command> reads a
1157 multiline data (several lines, the data are ended with
1158 a single period '.')
1159 from the given stream and store it into the given
1160 multiline buffer (multiline_buffer). progr_rate should be 0
1161 and progr_fun <command>NULL</command> (deprecated things).
1162 <command>stream_buffer</command> is a buffer used for internal
1163 work of the function.
1164 size should be 0 (deprecated things).
1165 </para>
1166
1167 <programlisting role="C">
1168int mailstream_is_end_multiline(char * line);
1169 </programlisting>
1170
1171 <para>
1172 returns 1 if the line is an end of multiline data (a single
1173 period '.', eventually with CR and/or LF). 0 is returned
1174 otherwise.
1175 </para>
1176
1177 <programlisting role="C">
1178int mailstream_send_data(mailstream * s, char * message,
1179 size_t size,
1180 size_t progr_rate,
1181 progress_function * progr_fun);
1182 </programlisting>
1183
1184 <para>
1185 sends multiline data to the given stream.
1186 <command>size</command> is the size of the data.
1187 <command>progr_rate</command> and <command>progr_fun</command>
1188 are deprecated. <command>progr_rate</command> must be 0,
1189 <command>progr_fun</command> must be NULL.
1190 </para>
1191
1192 <sect2 id="mailstream-socket">
1193 <title>socket stream</title>
1194
1195 <programlisting role="C">
1196mailstream * mailstream_socket_open(int fd);
1197 </programlisting>
1198
1199 <para>
1200 <command>mailstream_socket_open()</command> will open a
1201 clear-text socket.
1202 </para>
1203 </sect2>
1204
1205 <sect2 id="mailstream-ssl">
1206 <title>TLS stream</title>
1207
1208 <programlisting role="C">
1209mailstream * mailstream_ssl_open(int fd);
1210 </programlisting>
1211
1212 <para>
1213 <command>mailstream_ssl_open()</command> will open a
1214 TLS/SSL socket.
1215 </para>
1216 </sect2>
1217 </sect1>
1218
1219 <!-- mailstream_low -->
1220 <sect1 id="mailstream-low">
1221 <title>non-buffered I/O</title>
1222
1223 <programlisting role="C">
1224#include &lt;libetpan/libetpan.h&gt;
1225
1226struct mailstream_low_driver {
1227 ssize_t (* mailstream_read)(mailstream_low *, void *, size_t);
1228 ssize_t (* mailstream_write)(mailstream_low *, void *, size_t);
1229 int (* mailstream_close)(mailstream_low *);
1230 int (* mailstream_get_fd)(mailstream_low *);
1231 void (* mailstream_free)(mailstream_low *);
1232};
1233
1234typedef struct mailstream_low_driver mailstream_low_driver;
1235
1236struct _mailstream_low {
1237 void * data;
1238 mailstream_low_driver * driver;
1239};
1240 </programlisting>
1241
1242 <para>
1243 <command>mailstream_low</command> is a non-buffered stream.
1244 </para>
1245
1246 <para>
1247 The <command>mailstream_low_driver</command> is a set of
1248 functions used to access the stream.
1249 </para>
1250
1251 <itemizedlist>
1252 <listitem>
1253 <para>
1254 <command>mailstream_read/write/close()</command> is the same
1255 interface as <command>read/write/close()</command>
1256 system calls, except that the file descriptor is replaced with the
1257 <command>mailstream_low</command> structure.
1258 </para>
1259 </listitem>
1260 <listitem>
1261 <para>
1262 <command>mailstream_get_fd()</command> returns the file
1263 descriptor used for this non-buffered stream.
1264 </para>
1265 </listitem>
1266 <listitem>
1267 <para>
1268 <command>mailstream_free()</command> is in charge to free
1269 the internal structure of the mailstream_low and the
1270 mailstream_low itself.
1271 </para>
1272 </listitem>
1273 </itemizedlist>
1274
1275 <programlisting role="C">
1276mailstream_low * mailstream_low_new(void * data,
1277 mailstream_low_driver * driver);
1278 </programlisting>
1279
1280 <para>
1281 mailstream_low_new() creates a low-level mailstream with the
1282 given internal structure (data) and using the given set of
1283 functions (driver).
1284 </para>
1285
1286 <programlisting role="C">
1287ssize_t mailstream_low_write(mailstream_low * s, void * buf, size_t count);
1288
1289ssize_t mailstream_low_read(mailstream_low * s, void * buf, size_t count);
1290
1291int mailstream_low_close(mailstream_low * s);
1292
1293int mailstream_low_get_fd(mailstream_low * s);
1294
1295void mailstream_low_free(mailstream_low * s);
1296 </programlisting>
1297
1298 <para>
1299 Each of these calls will call the corresponding function defined
1300 in the driver.
1301 </para>
1302
1303 </sect1>
1304
1305
1306 <!-- MMAPString -->
1307 <sect1>
1308 <title>strings</title>
1309
1310 <programlisting role="C">
1311#include &lt;libetpan/libetpan.h&gt;
1312
1313struct _MMAPString
1314{
1315 char * str;
1316 size_t len;
1317 size_t allocated_len;
1318 int fd;
1319 size_t mmapped_size;
1320};
1321
1322typedef struct _MMAPString MMAPString;
1323 </programlisting>
1324
1325 <para>
1326 MMAPString is a string which size that can increase automatically.
1327 </para>
1328
1329 <sect2 id="mmap-string-new">
1330 <title>constructor and destructor</title>
1331 <programlisting role="C">
1332MMAPString * mmap_string_new(const char * init);
1333
1334MMAPString * mmap_string_new_len(const char * init, size_t len);
1335
1336MMAPString * mmap_string_sized_new(size_t dfl_size);
1337
1338void mmap_string_free(MMAPString * string);
1339 </programlisting>
1340
1341 <para>
1342 <command>mmap_string_new()</command> allocates a new
1343 string. init is the intial value of the string.
1344 <command>NULL</command> will be returned on error.
1345 </para>
1346
1347 <para>
1348 <command>mmap_string_new_len()</command> allocates a new
1349 string. init is the intial value of the
1350 string, len is the length of the initial string.
1351 <command>NULL</command> will be returned on error.
1352 </para>
1353
1354 <para>
1355 <command>mmap_string_sized_new()</command> allocates a new
1356 string. dfl_size is the initial allocation of
1357 the string. <command>NULL</command> will be returned on error.
1358 </para>
1359
1360 <para>
1361 <command>mmap_string_free()</command> release the memory used
1362 by the string.
1363 </para>
1364 </sect2>
1365
1366 <sect2 id="mmap-string-assign">
1367 <title>string value modification</title>
1368 <programlisting role="C">
1369MMAPString * mmap_string_assign(MMAPString * string, const char * rval);
1370
1371MMAPString * mmap_string_truncate(MMAPString *string, size_t len);
1372 </programlisting>
1373
1374 <para>
1375 <command>mmap_string_assign()</command> sets a new value for
1376 the given string.
1377 <command>NULL</command> will be returned on error.
1378 </para>
1379
1380 <para>
1381 <command>mmap_string_truncate()</command> sets a length for
1382 the string.
1383 <command>NULL</command> will be returned on error.
1384 </para>
1385
1386 <programlisting role="C">
1387MMAPString * mmap_string_set_size (MMAPString * string, size_t len);
1388 </programlisting>
1389
1390 <para>
1391 sets the allocation of the string.
1392 <command>NULL</command> will be returned on error.
1393 </para>
1394 </sect2>
1395
1396 <sect2 id="mmap-string-append">
1397 <title>insertion in string, deletion in string</title>
1398 <programlisting role="C">
1399MMAPString * mmap_string_insert_len(MMAPString * string, size_t pos,
1400 const char * val, size_t len);
1401
1402MMAPString * mmap_string_append(MMAPString * string, const char * val);
1403
1404MMAPString * mmap_string_append_len(MMAPString * string,
1405 const char * val, size_t len);
1406
1407MMAPString * mmap_string_append_c(MMAPString * string, char c);
1408
1409MMAPString * mmap_string_prepend(MMAPString * string, const char * val);
1410
1411MMAPString * mmap_string_prepend_c(MMAPString * string, char c);
1412
1413MMAPString * mmap_string_prepend_len(MMAPString * string, const char * val,
1414 size_t len);
1415
1416MMAPString * mmap_string_insert(MMAPString * string, size_t pos,
1417 const char * val);
1418
1419MMAPString * mmap_string_insert_c(MMAPString *string, size_t pos,
1420 char c);
1421
1422MMAPString * mmap_string_erase(MMAPString * string, size_t pos,
1423 size_t len);
1424 </programlisting>
1425
1426 <para>
1427 For complexity here, n is the size of the given MMAPString,
1428 and len is the size of the string to insert.
1429 </para>
1430
1431 <para>
1432 <command>mmap_string_insert_len()</command> inserts the given
1433 string value of given length in the string at the given
1434 position. <command>NULL</command> will be returned on error.
1435 Complexity is O(n + len).
1436 </para>
1437
1438 <para>
1439 <command>mmap_string_append()</command> appends the given
1440 string value at the end of the string.
1441 <command>NULL</command> will be returned on error.
1442 Complexity is O(len).
1443 </para>
1444
1445 <para>
1446 <command>mmap_string_append_len()</command> appends the
1447 given string value of given length at the end of the
1448 string. <command>NULL</command> will be returned on error.
1449 Complexity is O(len).
1450 </para>
1451
1452 <para>
1453 <command>mmap_string_append_c()</command> appends the given
1454 character at the end of the string.
1455 <command>NULL</command> will be returned on error.
1456 Complexity is O(1).
1457 </para>
1458
1459 <para>
1460 <command>mmap_string_prepend()</command> insert the given
1461 string value at the beginning of the string.
1462 <command>NULL</command> will be returned on error.
1463 Complexity is O(n + len).
1464 </para>
1465
1466 <para>
1467 <command>mmap_string_prepend_c()</command> insert the given
1468 character at the beginning of the string.
1469 <command>NULL</command> will be returned on error.
1470 Complexity is O(n).
1471 </para>
1472
1473 <para>
1474 <command>mmap_string_prepend_len()</command> insert the given
1475 string value of given length at the beginning of the string.
1476 <command>NULL</command> will be returned on error.
1477 Complexity is O(n + len).
1478 </para>
1479
1480 <para>
1481 <command>mmap_string_insert()</command> inserts the given
1482 string value in the string at the given position.
1483 NULL will be returned on error.
1484 Complexity is O(n + len).
1485 </para>
1486
1487 <para>
1488 <command>mmap_string_insert_c()</command> inserts the given
1489 character in the string at the given position.
1490 NULL will be returned on error.
1491 Complexity is O(n).
1492 </para>
1493
1494 <para>
1495 <command>mmap_string_erase()</command> removes the given
1496 count of characters (len) at the given position of the
1497 string. <command>NULL</command> will be returned on error.
1498 Complexity is O(n).
1499 </para>
1500
1501 </sect2>
1502
1503 <sect2 id="mmap-string-ref">
1504 <title>referencing string</title>
1505 <programlisting role="C">
1506int mmap_string_ref(MMAPString * string);
1507
1508int mmap_string_unref(char * str);
1509 </programlisting>
1510
1511 <para>
1512 MMAPString provides a mechanism that let you use MMAPString
1513 like normal strings. You have first to use
1514 <command>mmap_string_ref()</command>, so that you notify
1515 that the string will be used as a normal string, then, you
1516 use <command>mmapstr-&gt;str</command> to refer to the
1517 string. When you have finished and you want to free a string
1518 corresponding to a <command>MMAPString</command>, you will
1519 use <command>mmap_string_unref</command>.
1520 </para>
1521
1522 <para>
1523 <command>mmap_string_ref()</command> references the string
1524 so that the array of characters can be used as a normal
1525 string then released with
1526 <command>mmap_string_unref()</command>.
1527 The array of characters will be obtained with string-&gt;str.
1528 returns -1 on error, 0 on success.
1529 </para>
1530 </sect2>
1531 </sect1>
1532 </chapter>
1533
1534 <!-- IMF -->
1535 <chapter id="imf">
1536 <title>Internet Message Format</title>
1537
1538 <para>
1539 libEtPan! implements Internet Message parser. Currently, format
1540 is RFC 2822.
1541 This module also allows to generate messages.
1542 </para>
1543
1544 <warning>
1545 <para>
1546 All allocation functions will take as argument allocated data
1547 and will store these data in the structure they will allocate.
1548 Data should be persistant during all the use of the structure
1549 and will be freed by the free function of the structure
1550 </para>
1551
1552 <para>
1553 allocation functions will return <command>NULL</command> on failure
1554
1555 functions returning integer will be returning one of the
1556 following error code:
1557 <command>MAILIMF_NO_ERROR</command>,
1558 <command>MAILIMF_ERROR_PARSE</command>,
1559 <command>MAILIMF_ERROR_MEMORY</command>,
1560 <command>MAILIMF_ERROR_INVAL</command>,
1561 or <command>MAILIMF_ERROR_FILE</command>.
1562 </para>
1563 </warning>
1564
1565 <sect1>
1566 <title>Quick start</title>
1567
1568 <para>
1569 You will need this module when you want to parse headers
1570 of messages or when you want to build message headers
1571 conformant to standards.
1572 </para>
1573
1574 <sect2>
1575 <title>Parse message headers</title>
1576 <para>
1577 You will use one of the four following functions, depending
1578 on your needs :
1579 </para>
1580 <itemizedlist>
1581 <listitem>
1582 <para>
1583 <command>mailimf_envelope_and_optional_fields_parse</command>
1584 (<xref linkend="mailimf-envelope-and-optional-fields-parse">),
1585 </para>
1586 </listitem>
1587 <listitem>
1588 <para>
1589 <command>mailimf_envelope_fields_parse</command>
1590 (<xref linkend="mailimf-envelope-fields-parse">),
1591 </para>
1592 </listitem>
1593 <listitem>
1594 <para>
1595 <command>mailimf_optional_fields_parse</command>
1596 (<xref linkend="mailimf-optional-fields-parse">),
1597 </para>
1598 </listitem>
1599 <listitem>
1600 <para>
1601 <command>mailimf_fields_parse</command>
1602 (<xref linkend="mailimf-fields-parse">).
1603 </para>
1604 </listitem>
1605 </itemizedlist>
1606 </sect2>
1607
1608 <sect2>
1609 <title>Render the message headers</title>
1610 <para>
1611 Build your message headers, then use
1612 <command>mailimf_fields_write</command>
1613 (<xref linkend="mailimf-fields-write">)
1614 to render the headers.
1615 </para>
1616 </sect2>
1617 </sect1>
1618
1619 <sect1>
1620 <title>Data types</title>
1621 <!-- mailimf_mailbox -->
1622 <sect2 id="mailimf-mailbox">
1623 <title>mailimf_mailbox - mailbox</title>
1624 <para>
1625#include &lt;libetpan/libetpan.h&gt;
1626
1627struct mailimf_mailbox {
1628 char * mb_display_name; /* can be NULL */
1629 char * mb_addr_spec; /* != NULL */
1630};
1631
1632struct mailimf_mailbox *
1633mailimf_mailbox_new(char * mb_display_name, char * mb_addr_spec);
1634
1635void mailimf_mailbox_free(struct mailimf_mailbox * mailbox);
1636 </para>
1637
1638 <para>
1639 This is an email mailbox with a display name.
1640 </para>
1641
1642 <example>
1643 <title>example of mailbox</title>
1644 <programlisting>
1645DINH Viet Hoa &lt;hoa@users.sourceforge.net&gt;
1646 </programlisting>
1647 </example>
1648
1649 <para>
1650 <command>mailimf_mailbox_new</command> creates and
1651 initializes a data structure with a value.
1652 Strings given as argument are referenced by the created
1653 object and will be freed if the object is released.
1654 </para>
1655
1656 <para>
1657 <command>mailimf_mailbox_free</command> frees memory used by
1658 the structure and substructures will also be released.
1659 </para>
1660
1661 <example>
1662 <title>mailbox creation and display</title>
1663 <programlisting role="C">
1664#include &lt;libetpan/libetpan.h&gt;
1665
1666int main(int argc, char ** argv)
1667{
1668 struct mailimf_mailbox * mb;
1669 char * display_name;
1670 char * address;
1671
1672 display_name = strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?=");
1673 address = strdup("dinh.viet.hoa@free.fr");
1674 mb = mailimf_mailbox_new(str, address);
1675 /* do the things */
1676 mailimf_mailbox_free(mb);
1677
1678 return 0;
1679}
1680
1681/* display mailbox information */
1682
1683#include &lt;libetpan/libetpan.h&gt;
1684#include &lt;stdio.h&gt;
1685
1686void display_mailbox(struct mailimf_mailbox * mb)
1687{
1688 if (mb-&gt;mb_display_name != NULL)
1689 printf("display name: %s\n", mb-&gt;mb_display_name);
1690 printf("address specifier : %s\n", mb-&gt;mb_addr_spec);
1691}
1692 </programlisting>
1693 </example>
1694 </sect2>
1695
1696 <!-- mailimf_address -->
1697 <sect2 id="mailimf-address">
1698 <title>mailimf_address - address</title>
1699
1700 <programlisting role="C">
1701#include &lt;libetpan/libetpan.h&gt;
1702
1703struct mailimf_address {
1704 int ad_type;
1705 union {
1706 struct mailimf_mailbox * ad_mailbox; /* can be NULL */
1707 struct mailimf_group * ad_group; /* can be NULL */
1708 } ad_data;
1709};
1710
1711struct mailimf_address *
1712mailimf_address_new(int ad_type, struct mailimf_mailbox * ad_mailbox,
1713 struct mailimf_group * ad_group);
1714
1715void mailimf_address_free(struct mailimf_address * address);
1716 </programlisting>
1717
1718 <para>
1719 This is a mailbox or a group of mailbox.
1720 </para>
1721
1722 <itemizedlist>
1723 <listitem>
1724 <para>
1725 <command>ad_type</command> can be MAILIMF_ADDRESS_MAILBOX or
1726 <command>MAILIMF_ADDRESS_GROUP</command>.
1727 </para>
1728 </listitem>
1729 <listitem>
1730 <para>
1731 <command>ad_data.ad_mailbox</command> is a mailbox if
1732 <command>ad_type</command> is
1733 <command>MAILIMF_ADDRESS_MAILBOX</command>
1734 see <xref linkend="mailimf-mailbox">)
1735 </para>
1736 </listitem>
1737 <listitem>
1738 <para>
1739 <command>ad_data.group</command> is a group if type is
1740 <command>MAILIMF_ADDRESS_GROUP</command>.
1741 see <xref linkend="mailimf-group">)
1742 </para>
1743 </listitem>
1744 </itemizedlist>
1745
1746 <para>
1747 <command>mailimf_address_new()</command> creates and initializes
1748 a data structure with a value.
1749 Structures given as argument are referenced by the created
1750 object and will be freed if the object is released.
1751 </para>
1752
1753 <para>
1754 <command>mailimf_address_free</command> frees memory used by
1755 the structure and substructures will also be released.
1756 </para>
1757
1758 <example>
1759 <title>address creation and display</title>
1760 <programlisting role="C">
1761/* creates an address of type mailbox */
1762
1763#include &lt;libetpan/libetpan.h&gt;
1764
1765int main(int argc, char ** argv)
1766{
1767 struct mailimf_address * a_mb;
1768 struct mailimf_mailbox * mb;
1769 char * display_name;
1770 char * address;
1771
1772 display_name = strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?=");
1773 address = strdup("dinh.viet.hoa@free.fr");
1774 mb = mailimf_mailbox_new(str, address);
1775
1776 a_mb = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
1777 /* do the things */
1778 mailimf_address_free(a_mb);
1779}
1780
1781/* creates an address of type group */
1782
1783#include &lt;libetpan/libetpan.h&gt;
1784
1785int main(int argc, char ** argv)
1786{
1787 struct mailimf_address * a_g;
1788 struct mailimf_group * g;
1789 char * display_name;
1790
1791 display_name = strdup("undisclosed-recipient");
1792 g = mailimf_group_new(display_name, NULL);
1793
1794 a_g = mailimf_address_new(MAILIMF_ADDRESS_GROUP, NULL, g);
1795 /* do the things */
1796 mailimf_address_free(a_g);
1797
1798 return 0;
1799}
1800
1801/* display the content of an address */
1802
1803#include &lt;libetpan/libetpan.h&gt;
1804
1805void display_address(struct mailimf_address * a)
1806{
1807 clistiter * cur;
1808
1809 switch (a-&gt;ad_type) {
1810 case MAILIMF_ADDRESS_GROUP:
1811 display_mailimf_group(a-&gt;ad_data.ad_group);
1812 break;
1813
1814 case MAILIMF_ADDRESS_MAILBOX:
1815 display_mailimf_mailbox(a-&gt;ad_data.ad_mailbox);
1816 break;
1817 }
1818}
1819 </programlisting>
1820 </example>
1821 </sect2>
1822
1823 <!-- mailimf_mailbox_list -->
1824 <sect2 id="mailimf-mailbox-list">
1825 <title>mailimf_mailbox_list - list of mailboxes</title>
1826
1827 <programlisting role="C">
1828#include &lt;libetpan/libetpan.h&gt;
1829
1830struct mailimf_mailbox_list {
1831 clist * mb_list; /* list of (struct mailimf_mailbox *), != NULL */
1832};
1833
1834struct mailimf_mailbox_list *
1835mailimf_mailbox_list_new(clist * mb_list);
1836
1837void mailimf_mailbox_list_free(struct mailimf_mailbox_list * mb_list);
1838 </programlisting>
1839
1840 <para>
1841 This is a list of mailboxes.
1842 </para>
1843
1844 <para>
1845 <command>mb_list</command> is a list of mailboxes. This is a
1846 <command>clist</command> which elements are of type
1847 mailimf_mailbox (see <xref linkend="mailimf-mailbox">).
1848 </para>
1849
1850 <para>
1851 <command>mailimf_mailbox_list_new()</command> creates and
1852 initializes a data structure with a value.
1853 Structures given as argument are referenced by the created
1854 object and will be freed if the object is released.
1855 </para>
1856
1857 <para>
1858 <command>mailimf_mailbox_list_free()</command> frees memory used by the
1859 structure and substructures will also be released.
1860 </para>
1861
1862 <example>
1863 <title>Creation and display of mailimf_mailbox_list</title>
1864 <programlisting role="C">
1865/* creates a list of mailboxes with two mailboxes */
1866
1867#include &lt;libetpan/libetpan.h&gt;
1868
1869int main(int argc, char ** argv)
1870{
1871 struct mailimf_group * g;
1872 char * display_name;
1873 struct mailimf_mailbox_list * mb_list;
1874 clist * list;
1875
1876 list = clist_new();
1877 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
1878 strdup("dinh.viet.hoa@free.fr"));
1879 list = clist_append(mb);
1880 mb = mailimf_mailbox_new(strdup("Christophe GIAUME"),
1881 strdup("christophe@giaume.com"));
1882 list = clist_append(mb);
1883
1884 mb_list = mailimf_mailbox_list_new(list);
1885 /* do the things */
1886 mailimf_mailbox_list_free(mb_list);
1887
1888 return 0;
1889}
1890
1891/* display a list of mailboxes */
1892
1893#include &lt;libetpan/libetpan.h&gt;
1894#include &lt;stdio.h&gt;
1895
1896void display_mailbox_list(struct mailimf_mailbox_list * mb_list)
1897{
1898 clistiter * cur;
1899
1900 for(cur = clist_begin(mb_list-&gt;mb_list) ; cur != NULL ;
1901 cur = clist_next(cur)) {
1902 struct mailimf_mailbox * mb;
1903
1904 mb = clist_content(cur);
1905
1906 display_mailbox(mb);
1907 printf("\n");
1908 }
1909}
1910 </programlisting>
1911 </example>
1912 </sect2>
1913
1914 <!-- mailimf_address_list -->
1915 <sect2 id="mailimf-address-list">
1916 <title>mailimf_address_list - list of addresses</title>
1917
1918 <programlisting role="C">
1919#include &lt;libetpan/libetpan.h&gt;
1920
1921struct mailimf_address_list {
1922 clist * ad_list; /* list of (struct mailimf_address *), != NULL */
1923};
1924
1925struct mailimf_address_list *
1926mailimf_address_list_new(clist * ad_list);
1927
1928void mailimf_address_list_free(struct mailimf_address_list * addr_list);
1929 </programlisting>
1930
1931 <para>
1932 This is a list of addresses.
1933 </para>
1934
1935 <para>
1936 <command>ad_list</command> is a list of addresses. This is a
1937 <command>clist</command> which elements are
1938 of type mailimf_address (see <xref linkend="mailimf-address">).
1939 </para>
1940
1941 <para>
1942 <command>mailimf_address_list_new()</command> creates and
1943 initializes a data structure with
1944 a value. Structures given as argument are referenced by the
1945 created object and will be freed if the object is released.
1946 </para>
1947
1948 <para>
1949 <command>mailimf_address_list_free()</command> frees memory
1950 used by the structure and substructures will also be released.
1951 </para>
1952
1953 <example>
1954 <title>creation and display of list of addresses</title>
1955 <programlisting role="C">
1956/* creates a list of addresses with two addresses */
1957
1958#include &lt;libetpan/libetpan.h&gt;
1959
1960int main(int argc, char ** argv)
1961{
1962 struct mailimf_address_list * addr_list;
1963 clist * list;
1964 struct mailimf_mailbox * mb;
1965 struct mailimf_address * addr;
1966
1967 list = clist_new();
1968 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
1969 strdup("dinh.viet.hoa@free.fr"));
1970 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
1971 list = clist_append(addr);
1972
1973 mb = mailimf_mailbox_new(strdup("Christophe GIAUME"),
1974 strdup("christophe@giaume.com"));
1975 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
1976 list = clist_append(addr);
1977
1978 addr_list = mailimf_address_list_new(list);
1979 /* do the things */
1980 mailimf_address_list_free(mb_list);
1981
1982 return 0;
1983}
1984
1985/* display a list of addresses */
1986
1987#include &lt;libetpan/libetpan.h&gt;
1988#include &lt;stdio.h&gt;
1989
1990void display_address_list(struct mailimf_address_list * addr_list)
1991{
1992 clistiter * cur;
1993
1994 for(cur = clist_begin(addr_list-&gt;ad_list) ; cur != NULL ;
1995 cur = clist_next(cur)) {
1996 struct mailimf_address * addr;
1997
1998 addr = clist_content(cur);
1999
2000 display_address(addr);
2001 printf("\n");
2002 }
2003}
2004 </programlisting>
2005 </example>
2006 </sect2>
2007
2008 <!-- mailimf_group -->
2009 <sect2 id="mailimf-group">
2010 <title>mailimf_group - named group of mailboxes</title>
2011 <programlisting role="C">
2012#include &lt;libetpan/libetpan.h&gt;
2013
2014struct mailimf_group {
2015 char * grp_display_name; /* != NULL */
2016 struct mailimf_mailbox_list * grp_mb_list; /* can be NULL */
2017};
2018
2019struct mailimf_group *
2020mailimf_group_new(char * grp_display_name,
2021 struct mailimf_mailbox_list * grp_mb_list);
2022
2023void mailimf_group_free(struct mailimf_group * group);
2024 </programlisting>
2025
2026 <para>
2027 This is a list of mailboxes tagged with a name.
2028 </para>
2029
2030 <example>
2031 <title>example of group</title>
2032 <programlisting>
2033 they play music: &lt;steve@morse.foo&gt;, &lt;neal@morse.foo&gt;,
2034 &lt;yngwie@malmsteen.bar&gt;, &lt;michael@romeo.bar&gt;;
2035 </programlisting>
2036 </example>
2037
2038 <para>
2039 <command>grp_display_name</command> is the name that will be
2040 displayed for this group,
2041 for example '<command>group_name</command>' in
2042 '<command>group_name: address1@domain1,
2043 address2@domain2;</command>'.
2044 This must be allocated with malloc().
2045 <command>grp_mb_list</command> is a list of mailboxes
2046 (see <xref linkend="mailimf-mailbox-list">).
2047 </para>
2048
2049 <para>
2050 <command>mailimf_group_new()</command> creates and initializes
2051 a data structure with a value.
2052 Structures given as argument are referenced by the created
2053 object and will be freed if the object is released.
2054 </para>
2055
2056 <para>
2057 <command>mailimf_group_free()</command> frees memory used by
2058 the structure and substructures will also be released.
2059 </para>
2060
2061 <example>
2062 <title>creation and display of a group</title>
2063 <programlisting role="C">
2064/* creates an empty group */
2065
2066#include &lt;libetpan/libetpan.h&gt;
2067
2068int main(int argc, char ** argv)
2069{
2070 struct mailimf_group * g;
2071 char * display_name;
2072
2073 display_name = strdup("undisclosed-recipient");
2074 g = mailimf_group_new(display_name, NULL);
2075 /* do the things */
2076 mailimf_group_free(g);
2077}
2078
2079/* creates a group with two mailboxes */
2080
2081#include &lt;libetpan/libetpan.h&gt;
2082
2083int main(int argc, char ** argv)
2084{
2085 struct mailimf_group * g;
2086 char * display_name;
2087 struct mailimf_mailbox_list * mb_list;
2088 struct mailimf_mailbox * mb;
2089 clist * list;
2090
2091 list = clist_new();
2092 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
2093 strdup("dinh.viet.hoa@free.fr"));
2094 list = clist_append(mb);
2095 mb = mailimf_mailbox_new(strdup("Christophe GIAUME"),
2096 strdup("christophe@giaume.com"));
2097 list = clist_append(mb);
2098
2099 mb_list = mailimf_mailbox_list_new(list);
2100
2101 display_name = strdup("my_group");
2102 g = mailimf_group_new(display_name, mb_list);
2103 /* do the things */
2104 mailimf_group_free(g);
2105
2106 return 0;
2107}
2108
2109/* display content of group */
2110
2111#include &lt;libetpan/libetpan.h&gt;
2112#include &lt;stdio.h&gt;
2113
2114void display_group(struct mailimf_group * group)
2115{
2116 printf("name of the group: %s\n", a-&gt;group-&gt;display_name);
2117 for(cur = clist_begin(a-&gt;group-&gt;mb_list-&gt;list) ; cur != NULL ;
2118 cur = clist_next(cur)) {
2119 struct mailimf_mailbox * mb;
2120
2121 mb = clist_content(cur);
2122 display_mailbox(mb);
2123 printf("\n");
2124 }
2125}
2126 </programlisting>
2127 </example>
2128 </sect2>
2129
2130 <!-- mailimf_date_time -->
2131 <sect2 id="mailimf-date-time">
2132 <title>mailimf_date_time - date of a message</title>
2133
2134 <para>
2135#include &lt;libetpan/libetpan.h&gt;
2136
2137struct mailimf_date_time {
2138 int dt_day;
2139 int dt_month;
2140 int dt_year;
2141 int dt_hour;
2142 int dt_min;
2143 int dt_sec;
2144 int dt_zone;
2145};
2146
2147struct mailimf_date_time *
2148mailimf_date_time_new(int dt_day, int dt_month, int dt_year,
2149 int dt_hour, int dt_min, int dt_sec, int dt_zone);
2150
2151void mailimf_date_time_free(struct mailimf_date_time * date_time);
2152 </para>
2153
2154 <para>
2155 This is the date and time of a message.
2156 For example :
2157 </para>
2158 <example>
2159 <title>example of date</title>
2160 <programlisting>
2161Thu, 11 Dec 2003 00:15:02 +0100.
2162 </programlisting>
2163 </example>
2164
2165 <itemizedlist>
2166 <listitem>
2167 <para>
2168 <command>dt_day</command> is the day of month (1 to 31)
2169 </para>
2170 </listitem>
2171 <listitem>
2172 <para>
2173 <command>dt_month</command> (1 to 12)
2174 </para>
2175 </listitem>
2176 <listitem>
2177 <para>
2178 <command>dt_year</command> (4 digits)
2179 </para>
2180 </listitem>
2181 <listitem>
2182 <para>
2183 <command>dt_hour</command> (0 to 23)
2184 </para>
2185 </listitem>
2186 <listitem>
2187 <para>
2188 <command>dt_min</command> (0 to 59)
2189 </para>
2190 </listitem>
2191 <listitem>
2192 <para>
2193 <command>dt_sec</command> (0 to 59)
2194 </para>
2195 </listitem>
2196 <listitem>
2197 <para>
2198 <command>dt_zone</command> (this is the decimal value that
2199 we can read, for example: for
2200 '<command>-0200</command>', the value is
2201 <command>-200</command>).
2202 </para>
2203 </listitem>
2204 </itemizedlist>
2205
2206 <para>
2207 <command>mailimf_date_time_new()</command> creates and
2208 initializes a date structure with a value.
2209 </para>
2210
2211 <para>
2212 <command>mailimf_date_time_free()</command> frees memory used
2213 by the structure.
2214 </para>
2215
2216 <example>
2217 <title>creation and display of date</title>
2218 <programlisting role="C">
2219#include &lt;libetpan/libetpan.h&gt;
2220
2221int main(int argc, char ** argv)
2222{
2223 struct mailimf_date_time * d;
2224
2225 d = mailimf_date_time_new(9, 5, 2003, 3, 01, 40, -0200);
2226 /* do the things */
2227 mailimf_date_time_free(d);
2228
2229 return 0;
2230}
2231
2232/* display the date */
2233
2234#include &lt;libetpan/libetpan.h&gt;
2235#include &lt;stdio.h&gt;
2236
2237void display_date(struct mailimf_date_time * d)
2238{
2239 printf("%02i/%02i/%i %02i:%02i:%02i %+04i\n",
2240 d-&gt;dt_day, d-&gt;dt_month, d-&gt;dt_year,
2241 d-&gt;dt_hour, d-&gt;dt_min, d-&gt;dt_sec, d-&gt;dt_zone);
2242}
2243 </programlisting>
2244 </example>
2245 </sect2>
2246
2247 <!-- mailimf_orig_date -->
2248 <sect2 id="mailimf-orig-date">
2249 <title>mailimf_orig_date - parsed content of date header</title>
2250
2251 <programlisting role="C">
2252#include &lt;libetpan/libetpan.h&gt;
2253
2254struct mailimf_orig_date {
2255 struct mailimf_date_time * dt_date_time; /* != NULL */
2256};
2257
2258struct mailimf_orig_date * mailimf_orig_date_new(struct mailimf_date_time *
2259 dt_date_time);
2260
2261void mailimf_orig_date_free(struct mailimf_orig_date * orig_date);
2262 </programlisting>
2263
2264 <para>
2265 This is the content of a header <command>Date</command> or
2266 <command>Resent-Date</command>.
2267 It encapsulates a mailimf_date_time
2268 </para>
2269
2270 <para>
2271 <command>dt_date_time</command> is the parsed date
2272 (see <xref linkend="mailimf-date-time">).
2273 </para>
2274
2275 <para>
2276 <command>mailimf_orig_date_new()</command> creates and
2277 initializes a data structure with
2278 a value. Structures given as argument are referenced by the
2279 created object and will be freed if the object is released.
2280 </para>
2281
2282 <para>
2283 <command>mailimf_orig_date_free()</command> frees memory used
2284 by the structure and substructures will also be released.
2285 </para>
2286
2287 <example>
2288 <title>creation and display of Date field</title>
2289 <programlisting role="C">
2290#include &lt;libetpan/libetpan.h&gt;
2291
2292int main(int argc, char ** argv)
2293{
2294 struct mailimf_date_time * d;
2295 struct mailimf_orig_date * date;
2296
2297 d = mailimf_date_time_new(9, 5, 2003, 3, 01, 40, -0200);
2298 date = mailimf_orig_date_new(d);
2299 /* do the things */
2300 mailimf_orig_date_free(date);
2301
2302 return 0;
2303}
2304
2305/* display date header */
2306
2307#include &lt;libetpan/libetpan.h&gt;
2308
2309void display_orig_date(struct mailimf_orig_date * orig_date)
2310{
2311 display_date_time(d-&gt;dt_date_time);
2312}
2313 </programlisting>
2314 </example>
2315 </sect2>
2316
2317 <!-- mailimf_from -->
2318 <sect2 id="mailimf-from">
2319 <title>mailimf_from - parsed content of From header</title>
2320 <programlisting role="C">
2321#include &lt;libetpan/libetpan.h&gt;
2322
2323struct mailimf_from {
2324 struct mailimf_mailbox_list * frm_mb_list; /* != NULL */
2325};
2326
2327struct mailimf_from *
2328mailimf_from_new(struct mailimf_mailbox_list * frm_mb_list);
2329
2330void mailimf_from_free(struct mailimf_from * from);
2331 </programlisting>
2332
2333 <para>
2334 This is the content of a header <command>From</command> or
2335 <command>Resent-From</command>.
2336 </para>
2337 <para>
2338 <command>frm_mb_list</command> is the parsed mailbox list
2339 (see <xref linkend="mailimf-mailbox-list">).
2340 </para>
2341
2342 <para>
2343 <command>mailimf_from_new()</command> creates and initializes
2344 a data structure with a value.
2345 Structures given as argument are referenced by the created
2346 object and will be freed if the object is released.
2347 </para>
2348
2349 <para>
2350 <command>mailimf_from_free()</command> frees memory used by
2351 the structure and substructures will also be released.
2352 </para>
2353
2354 <example>
2355 <title>creation and display of a From header</title>
2356 <programlisting role="C">
2357#include &lt;libetpan/libetpan.h&gt;
2358
2359int main(int argc, char ** argv)
2360{
2361 clist * list;
2362 struct mailimf_mailbox * mb;
2363 struct mailimf_mailbox_list * mb_list;
2364 struct mailimf_from * from;
2365
2366 list = clist_new();
2367 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
2368 strdup("dinh.viet.hoa@free.fr"));
2369 clist_append(list, mb);
2370 mb_list = mailimf_mailbox_list_new(list);
2371
2372 from = mailimf_from_new(mb_list);
2373 /* do the things */
2374 mailimf_from_free(from);
2375
2376 return 0;
2377}
2378
2379/* display content of from header */
2380
2381#include &lt;libetpan/libetpan.h&gt;
2382
2383void display_from(struct mailimf_from * from)
2384{
2385 display_mailbox_list(from-&gt;frm_mb_list);
2386}
2387 </programlisting>
2388 </example>
2389 </sect2>
2390
2391 <!-- mailimf_sender -->
2392 <sect2 id="mailimf-sender">
2393 <title>mailimf_sender - parsed content of Sender header</title>
2394
2395 <programlisting role="C">
2396#include &lt;libetpan/libetpan.h&gt;
2397
2398struct mailimf_sender {
2399 struct mailimf_mailbox * snd_mb; /* != NULL */
2400};
2401
2402struct mailimf_sender * mailimf_sender_new(struct mailimf_mailbox * snd_mb);
2403
2404void mailimf_sender_free(struct mailimf_sender * sender);
2405 </programlisting>
2406
2407 <para>
2408 This is the content of a header <command>Sender</command> or
2409 <command>Resent-Sender</command>.
2410 </para>
2411
2412 <para>
2413 <command>snd_mb</command> is the parsed mailbox
2414 (see <xref linkend="mailimf-mailbox">).
2415 </para>
2416
2417 <para>
2418 <command>mailimf_sender_new()</command> creates and
2419 initializes a data structure with a value.
2420 Structures given as argument are referenced by the created
2421 object and will be freed if the object is released.
2422 </para>
2423
2424 <para>
2425 <command>mailimf_sender_free()</command> This function frees
2426 memory used by the structure and substructures
2427 will also be released.
2428 </para>
2429
2430 <example>
2431 <title>creation and display of Sender field</title>
2432 <programlisting role="C">
2433#include &lt;libetpan/libetpan.h&gt;
2434
2435int main(int argc, char ** argv)
2436{
2437 struct mailimf_mailbox * mb;
2438 struct mailimf_sender * sender;
2439
2440 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
2441 strdup("dinh.viet.hoa@free.fr"));
2442
2443 sender = mailimf_sender_new(mb);
2444 /* do the things */
2445 mailimf_sender_free(sender);
2446
2447 return 0;
2448}
2449
2450#include &lt;libetpan/libetpan.h&gt;
2451#include &lt;stdio.h&gt;
2452
2453void display_sender(struct mailimf_sender * sender)
2454{
2455 display_mailbox(sender-&gt;snd_mb);
2456}
2457 </programlisting>
2458 </example>
2459 </sect2>
2460
2461 <!-- mailimf_reply_to -->
2462 <sect2 id="mailimf-reply-to">
2463 <title>mailimf_reply_to - parsed content of Reply-To header</title>
2464
2465 <programlisting role="C">
2466#include &lt;libetpan/libetpan.h&gt;
2467
2468struct mailimf_reply_to {
2469 struct mailimf_address_list * rt_addr_list; /* != NULL */
2470};
2471
2472struct mailimf_reply_to *
2473mailimf_reply_to_new(struct mailimf_address_list * rt_addr_list);
2474
2475void mailimf_reply_to_free(struct mailimf_reply_to * reply_to);
2476 </programlisting>
2477
2478 <para>
2479 This is the content of a header <command>Reply-To</command>.
2480 </para>
2481
2482 <para>
2483 <command>addr_list</command> is the parsed address list
2484 (see <xref linkend="mailimf-address-list">).
2485 </para>
2486
2487 <para>
2488 <command>mailimf_reply_to_new()</command> creates and
2489 initializes a data structure with a value. Structures given
2490 as argument are referenced by the created object and will be
2491 freed if the object is released.
2492 </para>
2493
2494 <para>
2495 <command>mailimf_reply_to_free()</command> frees memory used
2496 by the structure and substructures will also be released.
2497 </para>
2498
2499 <example>
2500 <title>creation and display of Reply-To field</title>
2501 <programlisting role="C">
2502#include &lt;libetpan/libetpan.h&gt;
2503
2504int main(int argc, char ** argv)
2505{
2506 clist * list;
2507 struct mailimf_mailbox * mb;
2508 struct mailimf_address * addr;
2509 struct mailimf_address_list * addr_list;
2510 struct mailimf_reply_to * reply_to;
2511
2512 list = clist_new();
2513
2514 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
2515 strdup("dinh.viet.hoa@free.fr"));
2516 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
2517 clist_append(list, addr);
2518
2519 mb = mailimf_mailbox_new(strdup("Christophe GIAUME"),
2520 strdup("christophe@giaume.com"));
2521 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
2522 clist_append(list, addr);
2523
2524 addr_list = mailimf_address_list_new(list);
2525
2526 reply_to = mailimf_reply_to_new(addr_list);
2527 /* do the things */
2528 mailimf_reply_to_free(reply_to);
2529
2530 return 0;
2531}
2532
2533/* display Reply-To header */
2534
2535#include &lt;libetpan/libetpan.h&gt;
2536
2537void display_reply_to(struct mailimf_reply_to * reply_to)
2538{
2539 display_address_list(reply_to-&gt;addr_list);
2540}
2541 </programlisting>
2542 </example>
2543 </sect2>
2544
2545 <!-- mailimf_to -->
2546 <sect2 id="mailimf-to">
2547 <title>mailimf_to - parsed content of To header</title>
2548
2549 <programlisting role="C">
2550 struct mailimf_to {
2551 struct mailimf_address_list * to_addr_list; /* != NULL */
2552};
2553
2554struct mailimf_to * mailimf_to_new(struct mailimf_address_list * to_addr_list);
2555
2556void mailimf_to_free(struct mailimf_to * to);
2557 </programlisting>
2558
2559 <para>
2560 This is the content of a header <command>To</command> or
2561 <command>Resent-To</command>.
2562 </para>
2563
2564 <para>
2565 <command>to_addr_list</command> is the parsed address list
2566 (see <xref linkend="mailimf-address-list">).
2567 </para>
2568
2569 <para>
2570 <command>mailimf_to_new()</command> creates and initializes a
2571 data structure with a value. Structures given as argument
2572 are referenced by the created
2573 object and will be freed if the object is released.
2574 </para>
2575
2576 <para>
2577 <command>mailimf_to_free()</command> frees memory used by the
2578 structure and substructures will also be released.
2579 </para>
2580
2581 <example>
2582 <title>creation and display of To field</title>
2583 <programlisting role="C">
2584#include &lt;libetpan/libetpan.h&gt;
2585
2586int main(int argc, char ** argv)
2587{
2588 clist * list;
2589 struct mailimf_mailbox * mb;
2590 struct mailimf_address * addr;
2591 struct mailimf_address_list * addr_list;
2592 struct mailimf_to * to;
2593
2594 list = clist_new();
2595
2596 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
2597 strdup("dinh.viet.hoa@free.fr"));
2598 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
2599 clist_append(list, addr);
2600
2601 mb = mailimf_mailbox_new(strdup("Christophe GIAUME"),
2602 strdup("christophe@giaume.com"));
2603 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
2604 clist_append(list, addr);
2605
2606 addr_list = mailimf_address_list_new(list);
2607
2608 to = mailimf_to_new(addr_list);
2609 /* do the things */
2610 mailimf_to_free(to);
2611
2612 return 0;
2613}
2614
2615/* display To header */
2616
2617#include &lt;libetpan/libetpan.h&gt;
2618
2619void display_to(struct mailimf_to * to)
2620{
2621 display_address_list(to-&gt;to_addr_list);
2622}
2623 </programlisting>
2624 </example>
2625 </sect2>
2626
2627 <!-- mailimf_cc -->
2628 <sect2 id="mailimf-cc">
2629 <title>mailimf_cc - parsed content of Cc</title>
2630
2631<programlisting>
2632#include &lt;libetpan/libetpan.h&gt;
2633
2634struct mailimf_cc {
2635 struct mailimf_address_list * cc_addr_list; /* != NULL */
2636};
2637
2638struct mailimf_cc *
2639mailimf_cc_new(struct mailimf_address_list * cc_addr_list);
2640
2641void mailimf_cc_free(struct mailimf_cc * cc);
2642</programlisting>
2643
2644 <para>
2645 This is the content of a header <command>Cc</command> or
2646 <command>Resent-Cc</command>.
2647 </para>
2648
2649 <para>
2650 <command>cc_addr_list</command> is the parsed address list
2651 (see <xref linkend="mailimf-address-list">).
2652 </para>
2653
2654 <para>
2655 <command>mailimf_cc_new()</command> creates and initializes a
2656 data structure with a value. Structures given as argument
2657 are referenced by the created object and will be freed if
2658 the object is released.
2659 </para>
2660
2661 <para>
2662 <command>mailimf_cc_free()</command> This function frees
2663 memory used by the structure and substructures will also be
2664 released.
2665 </para>
2666
2667 <example>
2668 <title>creation and display of Cc field</title>
2669 <programlisting role="C">
2670#include &lt;libetpan/libetpan.h&gt;
2671
2672int main(int argc, char ** argv)
2673{
2674 clist * list;
2675 struct mailimf_mailbox * mb;
2676 struct mailimf_address * addr;
2677 struct mailimf_address_list * addr_list;
2678 struct mailimf_cc * cc;
2679
2680 list = clist_new();
2681
2682 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
2683 strdup("dinh.viet.hoa@free.fr"));
2684 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
2685 clist_append(list, addr);
2686
2687 mb = mailimf_mailbox_new(strdup("Christophe GIAUME"),
2688 strdup("christophe@giaume.com"));
2689 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
2690 clist_append(list, addr);
2691
2692 addr_list = mailimf_address_list_new(list);
2693
2694 cc = mailimf_cc_new(addr_list);
2695 /* do the things */
2696 mailimf_cc_free(cc);
2697
2698 return 0;
2699}
2700
2701/* display content of Cc field */
2702
2703#include &lt;libetpan/libetpan.h&gt;
2704
2705void display_cc(struct mailimf_cc * cc)
2706{
2707 display_address_list(cc-&gt;cc_addr_list);
2708}
2709
2710 </programlisting>
2711 </example>
2712
2713 </sect2>
2714
2715 <!-- mailimf_bcc -->
2716 <sect2 id="mailimf-bcc">
2717 <title>mailimf_bcc - parsed content of Bcc field</title>
2718
2719 <programlisting role="C">
2720#include &lt;libetpan/libetpan.h&gt;
2721
2722struct mailimf_bcc {
2723 struct mailimf_address_list * bcc_addr_list; /* can be NULL */
2724};
2725
2726struct mailimf_bcc *
2727mailimf_bcc_new(struct mailimf_address_list * bcc_addr_list);
2728
2729void mailimf_bcc_free(struct mailimf_bcc * bcc);
2730 </programlisting>
2731
2732 <para>
2733 This is the content of a header <command>Bcc</command> or
2734 <command>Resent-Bcc</command>.
2735 </para>
2736
2737 <para>
2738 <command>bcc_addr_list</command> is the parsed address list
2739 (see <xref linkend="mailimf-address-list">).
2740 </para>
2741
2742 <para>
2743 <command>mailimf_bcc_new()</command> creates and initializes a
2744 data structure with a value. Structures given as argument
2745 are referenced by the created object and will be freed if
2746 the object is released.
2747 </para>
2748
2749 <para>
2750 <command>mailimf_bcc_free()</command> frees memory used by the
2751 structure and substructures will also be released.
2752 </para>
2753
2754 <example>
2755 <title>creation and display of Bcc field</title>
2756 <programlisting role="C">
2757/* create visible Bcc */
2758
2759#include &lt;libetpan/libetpan.h&gt;
2760
2761int main(int argc, char ** argv)
2762{
2763 clist * list;
2764 struct mailimf_mailbox * mb;
2765 struct mailimf_address * addr;
2766 struct mailimf_address_list * addr_list;
2767 struct mailimf_bcc * bcc;
2768
2769 list = clist_new();
2770
2771 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
2772 strdup("dinh.viet.hoa@free.fr"));
2773 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
2774 clist_append(list, addr);
2775
2776 mb = mailimf_mailbox_new(strdup("Christophe GIAUME"),
2777 strdup("christophe@giaume.com"));
2778 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
2779 clist_append(list, addr);
2780
2781 addr_list = mailimf_address_list_new(list);
2782
2783 bcc = mailimf_bcc_new(addr_list);
2784 /* do the things */
2785 mailimf_bcc_free(bcc);
2786
2787 return 0;
2788}
2789
2790/* create unvisible Bcc */
2791
2792#include &lt;libetpan/libetpan.h&gt;
2793
2794int main(int argc, char ** argv)
2795{
2796 struct mailimf_bcc * bcc;
2797
2798 bcc = mailimf_bcc_new(NULL);
2799 /* do the things */
2800 mailimf_bcc_free(bcc);
2801
2802 return 0;
2803}
2804
2805/* display content of Bcc field */
2806
2807#include &lt;libetpan/libetpan.h&gt;
2808#include &lt;stdio.h&gt;
2809
2810void display_bcc(struct mailimf_bcc * bcc)
2811{
2812 if (bcc-&gt;addr_list == NULL) {
2813 printf("hidden Bcc\n");
2814 }
2815 else {
2816 display_address_list(bcc-&gt;bcc_addr_list);
2817 }
2818}
2819 </programlisting>
2820 </example>
2821 </sect2>
2822
2823 <!-- mailimf_message_id -->
2824 <sect2 id="mailimf-message-id">
2825 <title>mailimf_message_id - parsed content of Message-ID header</title>
2826
2827 <programlisting role="C">
2828#include &lt;libetpan/libetpan.h&gt;
2829
2830struct mailimf_message_id {
2831 char * mid_value; /* != NULL */
2832};
2833
2834struct mailimf_message_id * mailimf_message_id_new(char * mid_value);
2835
2836void mailimf_message_id_free(struct mailimf_message_id * message_id);
2837 </programlisting>
2838
2839 <para>
2840 This is the content of a header <command>Message-ID</command>
2841 or <command>Resent-Message-ID</command>. For example :
2842 </para>
2843
2844 <example>
2845 <title>example of Message-ID</title>
2846 <programlisting>
2847Message-ID: &lt;200312100009.43592@c01n-c01n.plop.P4N>&gt;
2848 </programlisting>
2849 </example>
2850
2851 <para>
2852 <command>mid_value</command> is the message identifier.
2853 It is not enclosed by angle bracket.
2854 </para>
2855
2856 <para>
2857 <command>mailimf_message_id_new()</command> This function
2858 creates and initializes a data structure with a value.
2859 Structures given as argument are referenced by the created
2860 object and will be freed if the object is released.
2861 </para>
2862
2863 <para>
2864 The given string is allocated with
2865 <command>malloc()</command> and is not enclosed by angle bracket.
2866 </para>
2867
2868 <para>
2869 <command>mailimf_message_id_free()</command> frees memory
2870 used by the structure and substructures will also be
2871 released.
2872 </para>
2873
2874 <example>
2875 <title>creation and display of Message-ID field</title>
2876 <programlisting role="C">
2877#include &lt;libetpan/libetpan.h&gt;
2878
2879int main(int argc, char ** argv)
2880{
2881 struct mailimf_message_id * msg_id;
2882 char * id;
2883
2884 id = strdup("1037197913.3dd26259752fa@imp.free.fr");
2885 msg_id = mailimf_message_id_new(id);
2886 /* do the things */
2887 mailimf_message_id_free(msg_id);
2888
2889 return 0;
2890}
2891
2892/* display message id */
2893
2894#include &lt;libetpan/libetpan.h&gt;
2895#include &lt;stdio.h&gt;
2896
2897void display_message_id(struct mailimf_message_id * msg_id)
2898{
2899 printf("%s\n", msg_id->mid_value);
2900}
2901 </programlisting>
2902 </example>
2903 </sect2>
2904
2905 <!-- mailimf_in_reply_to -->
2906 <sect2 id="mailimf-in-reply-to">
2907 <title>mailimf_in_reply_to - parsed content of In-Reply-To
2908 field</title>
2909
2910 <programlisting role="C">
2911#include &lt;libetpan/libetpan.h&gt;
2912
2913struct mailimf_in_reply_to {
2914 clist * mid_list; /* list of (char *), != NULL */
2915};
2916
2917struct mailimf_in_reply_to * mailimf_in_reply_to_new(clist * mid_list);
2918
2919void mailimf_in_reply_to_free(struct mailimf_in_reply_to * in_reply_to);
2920 </programlisting>
2921
2922 <para>
2923 content of a header <command>In-Reply-To</command>.
2924 For example :
2925 </para>
2926
2927 <programlisting>
2928In-Reply-To: &lt;etPan.3fd5fa29.4c3901c1.6b39@homer&gt;
2929 </programlisting>
2930
2931 <para>
2932 <command>mid_list</command> is a <command>clist</command>
2933 in which elements are message identifiers.
2934 their types are <command>(char *)</command> and they are
2935 allocated with <command>malloc()</command>.
2936 </para>
2937
2938 <para>
2939 <command>mailimf_in_reply_to_new()</command> creates and
2940 initializes a data structure with a value. Structures given
2941 as argument are referenced by the created object and will be
2942 freed if the object is released.
2943 </para>
2944
2945 <para>
2946 <command>mailimf_in_reply_to_free()</command> frees memory
2947 used by the structure and substructures will also be
2948 released.
2949 </para>
2950
2951 <example>
2952 <title>creation and display of In-Reply-To field</title>
2953 <programlisting>
2954#include &lt;libetpan/libetpan.h&gt;
2955
2956int main(int argc, char ** argv)
2957{
2958 struct mailimf_in_reply_to * in_reply_to;
2959 clist * msg_id_list;
2960
2961 msg_id_list = clist_new();
2962 clist_append(msg_id_list,
2963 strdup("etPan.3ebbcc18.4014197f.bc1@homer.invalid"));
2964
2965 in_reply_to = mailimf_in_reply_to_new(msg_id_list);
2966 /* do the things */
2967 mailimf_in_reply_to_free(in_reply_to);
2968
2969 return 0;
2970}
2971
2972/* display the content of mailimf_in_reply_to */
2973
2974#include &lt;libetpan/libetpan.h&gt;
2975#include &lt;stdio.h&gt;
2976
2977void display_in_reply_to(struct mailimf_in_reply_to * in_reply_to)
2978{
2979 clistiter * cur;
2980
2981 for(cur = clist_begin(in_reply_to-&gt;mid_list) ; cur != NULL ;
2982 cur = clist_next(cur)) {
2983 char * str;
2984
2985 str = clist_content(cur);
2986
2987 printf("%s\n", str);
2988 }
2989}
2990 </programlisting>
2991 </example>
2992 </sect2>
2993
2994 <!-- mailimf_references -->
2995 <sect2 id="mailimf-references">
2996 <title>mailimf_references - parsed content of References field</title>
2997
2998 <programlisting role="C">
2999#include &lt;libetpan/libetpan.h&gt;
3000
3001struct mailimf_references {
3002 clist * mid_list; /* list of (char *) */
3003 /* != NULL */
3004};
3005
3006struct mailimf_references * mailimf_references_new(clist * mid_list);
3007
3008void mailimf_references_free(struct mailimf_references * references);
3009 </programlisting>
3010
3011 <para>
3012 This is the content of a header <command>References</command>.
3013 For example :
3014 </para>
3015 <programlisting>
3016In-Reply-To: &lt;etPan.3fd5fa29.4c3901c1.6b39@homer&gt;
3017 &lt;3FD5FA78.A1D98E7@oleane.net&gt;
3018 &lt;etPan.3fd5fc69.2b349482.730e@homer&gt;
3019 </programlisting>
3020
3021 <para>
3022 <command>mid_list</command> is a <command>clist</command>
3023 in which elements are message identifiers.
3024 their types are <command>(char *)</command> and they are
3025 allocated with <command>malloc()</command>.
3026 </para>
3027
3028 <para>
3029 <command>mailimf_references_new()</command> creates and
3030 initializes a data structure with a value. Structures given
3031 as argument are referenced by the created object and will be
3032 freed if the object is released.
3033 </para>
3034
3035 <para>
3036 <command>mailimf_references_free()</command> frees memory
3037 used by the structure and substructures will also be
3038 released.
3039 </para>
3040
3041 <example>
3042 <title>creation and display of References field</title>
3043 <programlisting role="C">
3044#include &lt;libetpan/libetpan.h&gt;
3045
3046int main(int argc, char ** argv)
3047{
3048 struct mailimf_references * ref;
3049 clist * msg_id_list;
3050
3051 msg_id_list = clist_new();
3052 clist_append(msg_id_list,
3053 strdup("200304280144.23633.wim.delvaux@adaptiveplanet.com"));
3054 clist_append(msg_id_list,
3055 strdup("200304301153.19688.wim.delvaux@adaptiveplanet.com"));
3056 clist_append(msg_id_list,
3057 strdup("etPan.3eb29de4.5fc4d652.3f83@homer"));
3058
3059 ref = mailimf_references_new(msg_id_list);
3060 /* do the things */
3061 mailimf_in_reply_to_free(ref);
3062
3063 return 0;
3064}
3065
3066/* display references */
3067
3068#include &lt;libetpan/libetpan.h&gt;
3069#include &lt;stdio.h&gt;
3070
3071void display_references(struct mailimf_references * ref)
3072{
3073 clistiter * cur;
3074
3075 for(cur = clist_begin(ref-&gt;mid_list) ; cur != NULL ;
3076 cur = clist_next(cur)) {
3077 char * msg_id;
3078
3079 msg_id = clist_content(cur);
3080
3081 printf("%s\n", msg_id);
3082 }
3083}
3084 </programlisting>
3085 </example>
3086 </sect2>
3087
3088 <!-- mailimf_subject -->
3089 <sect2 id="mailimf-subject">
3090 <title>mailimf_subject - parsed content of Subject field</title>
3091
3092<programlisting role="C">
3093#include &lt;libetpan/libetpan.h&gt;
3094
3095struct mailimf_subject {
3096 char * sbj_value; /* != NULL */
3097};
3098
3099struct mailimf_subject * mailimf_subject_new(char * sbj_value);
3100
3101void mailimf_subject_free(struct mailimf_subject * subject);
3102</programlisting>
3103
3104 <para>
3105 This is the content of a header <command>Subject</command>.
3106 </para>
3107
3108 <para>
3109 <command>sbj_value</command> is the value of the field.
3110 </para>
3111
3112 <para>
3113 <command>mailimf_subject_new()</command> creates and
3114 initializes a data structure with a value.
3115 Structures given as argument are referenced by the created
3116 object and will be freed if the object is released.
3117 </para>
3118
3119 <para>
3120 <command>mailimf_subject_free</command> frees memory used by
3121 the structure and substructures will also be released.
3122 </para>
3123
3124 <example>
3125 <title>creation and display of Subject field</title>
3126 <programlisting role="C">
3127#include &lt;libetpan/libetpan.h&gt;
3128
3129int main(int argc, char ** argv)
3130{
3131 struct mailimf_subject * subject;
3132
3133 subject = mailimf_subject_new(strdup("example of subject"));
3134 /* do the things */
3135 mailimf_subject_free(subject);
3136
3137 return 0;
3138}
3139
3140/* display subject header */
3141
3142#include &lt;libetpan/libetpan.h&gt;
3143#include &lt;stdio.h&gt;
3144
3145void display_subject(struct mailimf_subject * subject)
3146{
3147 printf("%s\n", subject->value);
3148}
3149 </programlisting>
3150 </example>
3151 </sect2>
3152
3153 <!-- mailimf_comments -->
3154 <sect2 id="mailimf-comments">
3155 <title>mailimf_comments - parsed content of Comments field</title>
3156
3157 <programlisting role="C">
3158#include &lt;libetpan/libetpan.h&gt;
3159
3160struct mailimf_comments {
3161 char * cm_value; /* != NULL */
3162};
3163
3164struct mailimf_comments * mailimf_comments_new(char * cm_value);
3165
3166void mailimf_comments_free(struct mailimf_comments * comments);
3167 </programlisting>
3168
3169 <para>
3170 This is the content of a header <command>Comments</command>.
3171 </para>
3172
3173 <para>
3174 <command>cm_value</command> is the value of the field.
3175 </para>
3176
3177 <para>
3178 <command>mailimf_comments_new()</command> creates and
3179 initializes a data structure with a value.
3180 Structures given as argument are referenced by the created
3181 object and will be freed if the object is released.
3182 </para>
3183
3184 <para>
3185 <command>mailimf_comments_free()</command> frees memory used
3186 by the structure and substructures will also be released.
3187 </para>
3188
3189 <example>
3190 <title>creation and display of Comment field</title>
3191 <programlisting role="C">
3192#include &lt;libetpan/libetpan.h&gt;
3193
3194int main(int argc, char ** argv)
3195{
3196 struct mailimf_comments * comments;
3197
3198 comments = mailimf_comments_new(strdup("example of comment"));
3199 /* do the things */
3200 mailimf_comments_free(comments);
3201
3202 return 0;
3203}
3204
3205/* display the content of a comments */
3206
3207#include &lt;libetpan/libetpan.h&gt;
3208#include &lt;stdio.h&gt;
3209
3210void display_comments(struct mailimf_comments * comments)
3211{
3212 printf("%s\n", comments->cm_value);
3213}
3214 </programlisting>
3215 </example>
3216 </sect2>
3217
3218 <!-- mailimf_keywords -->
3219 <sect2 id="mailimf-keywords">
3220 <title>mailimf_keywords - parsed content of Keywords field</title>
3221
3222 <programlisting role="C">
3223#include &lt;libetpan/libetpan.h&gt;
3224
3225struct mailimf_keywords {
3226 clist * kw_list; /* list of (char *), != NULL */
3227};
3228
3229struct mailimf_keywords * mailimf_keywords_new(clist * kw_list);
3230
3231void mailimf_keywords_free(struct mailimf_keywords * keywords);
3232 </programlisting>
3233
3234 <para>
3235 This is the content of a header <command>Keywords</command>.
3236 </para>
3237
3238 <para>
3239 <command>kw_list</command> is the list of keywords. This is
3240 a list of <command>(char *)</command> allocated with malloc().
3241 </para>
3242
3243 <para>
3244 <command>mailimf_keywords_new()</command> creates and
3245 initializes a data structure with a value.
3246 Structures given as argument are referenced by the created
3247 object and will be freed if the object is released.
3248 </para>
3249
3250 <para>
3251 <command>mailimf_keywords_free()</command> frees memory used
3252 by the structure and substructures will also be released.
3253 </para>
3254
3255 <example>
3256 <title>creation and display of Keywords field</title>
3257 <programlisting role="C">
3258#include &lt;libetpan/libetpan.h&gt;
3259
3260int main(int argc, char ** argv)
3261{
3262 struct mailimf_keywords * keywords;
3263 clist * list;
3264
3265 list = clist_new();
3266 clist_append(list, strdup("sauerkraut"));
3267 clist_append(list, strdup("potatoes"));
3268 clist_append(list, strdup("cooking"));
3269
3270 keywords = mailimf_keywords_new(list);
3271 /* do the things */
3272 mailimf_keywords_free(keywords);
3273
3274 return 0;
3275}
3276
3277/* display the content of mailimf_in_reply_to */
3278
3279#include &lt;libetpan/libetpan.h&gt;
3280#include &lt;stdio.h&gt;
3281
3282void display_keywords(struct mailimf_keywords * kw)
3283{
3284 clistiter * cur;
3285
3286 for(cur = clist_begin(kw-&gt;kw_list) ; cur != NULL ;
3287 cur = clist_next(cur)) {
3288 char * str;
3289
3290 str = clist_content(cur);
3291
3292 printf("%s\n", str);
3293 }
3294}
3295 </programlisting>
3296 </example>
3297 </sect2>
3298
3299 <!-- mailimf_return -->
3300 <sect2 id="mailimf-return">
3301 <title>mailimf_return - parsed content of Return-Path field</title>
3302
3303 <programlisting role="C">
3304#include &lt;libetpan/libetpan.h&gt;
3305
3306struct mailimf_return {
3307 struct mailimf_path * ret_path; /* != NULL */
3308};
3309
3310struct mailimf_return *
3311mailimf_return_new(struct mailimf_path * ret_path);
3312
3313void mailimf_return_free(struct mailimf_return * return_path);
3314 </programlisting>
3315
3316 <para>
3317 This is the content of a header
3318 <command>Return-Path</command>.
3319 </para>
3320
3321 <para>
3322 <command>ret_path</command> is the parsed value of Return-Path
3323 (see <xref linkend="mailimf-path">).
3324 </para>
3325
3326 <para>
3327 <command>mailimf_return_new()</command> creates and
3328 initializes a data structure with a value.
3329 Structures given as argument are referenced by the created
3330 object and will be freed if the object is released.
3331 </para>
3332
3333 <para>
3334 <command>mailimf_return_free()</command> frees memory used
3335 by the structure and substructures will also be released.
3336 </para>
3337
3338 <example>
3339 <title>creation and display of Return-Path field</title>
3340 <programlisting role="C">
3341#include &lt;libetpan/libetpan.h&gt;
3342
3343int main(int argc, char ** argv)
3344{
3345 struct mailimf_path * path;
3346 struct mailimf_return * r;
3347
3348 path = mailimf_path_new(strdup("dinh.viet.hoa@free.fr"));
3349 r = mailimf_return_new(path);
3350 /* do the things */
3351 mailimf_return_free(r);
3352
3353 return 0;
3354}
3355
3356/* display return path */
3357
3358#include &lt;libetpan/libetpan.h&gt;
3359
3360void display_return(struct mailimf_return * r)
3361{
3362 display_path(r-&gt;ret_path);
3363}
3364 </programlisting>
3365 </example>
3366 </sect2>
3367
3368 <!-- mailimf_path -->
3369 <sect2 id="mailimf-path">
3370 <title>mailimf_path - address in Return-Path field</title>
3371
3372 <programlisting role="C">
3373#include &lt;libetpan/libetpan.h&gt;
3374
3375struct mailimf_path {
3376 char * pt_addr_spec; /* can be NULL */
3377};
3378
3379struct mailimf_path * mailimf_path_new(char * pt_addr_spec);
3380
3381void mailimf_path_free(struct mailimf_path * path);
3382 </programlisting>
3383
3384 <para>
3385 This is the encapsulation of address specifier for
3386 <command>Return-Path</command> content.
3387 </para>
3388
3389 <para>
3390 <command>pt_addr_spec</command> is a mailbox destination.
3391 </para>
3392
3393 <para>
3394 <command>mailimf_path_new()</command> creates and
3395 initializes a data structure with a value.
3396 Structures given as argument are referenced by the created
3397 object and will be freed if the object is released.
3398 </para>
3399
3400 <para>
3401 The given string is allocated with
3402 <command>malloc()</command>. This is a address
3403 specifier.
3404 </para>
3405
3406 <para>
3407 <command>mailimf_path_free()</command> frees memory used by
3408 the structure and substructures will also be released.
3409 </para>
3410
3411 <example>
3412 <title>Creation and display of return path</title>
3413 <programlisting role="C">
3414#include &lt;libetpan/libetpan.h&gt;
3415
3416int main(int argc, char ** argv)
3417{
3418 struct mailimf_path * path;
3419
3420 path = mailimf_path_new(strdup("dinh.viet.hoa@free.fr"));
3421 /* do the things */
3422 mailimf_path_free(r);
3423
3424 return 0;
3425}
3426
3427/* display return path */
3428
3429#include &lt;libetpan/libetpan.h&gt;
3430#include &lt;stdio.h&gt;
3431
3432void display_path(struct mailimf_path * path)
3433{
3434 printf("%s\n", path-&gt;pt_addr_spec);
3435}
3436 </programlisting>
3437 </example>
3438 </sect2>
3439
3440 <!-- mailimf_optional_field -->
3441 <sect2 id="mailimf-optional-field">
3442 <title>mailimf_optional_field - non-standard header</title>
3443
3444 <programlisting>
3445#include &lt;libetpan/libetpan.h&gt;
3446
3447struct mailimf_optional_field {
3448 char * fld_name; /* != NULL */
3449 char * fld_value; /* != NULL */
3450};
3451
3452struct mailimf_optional_field *
3453mailimf_optional_field_new(char * fld_name, char * fld_value);
3454
3455void mailimf_optional_field_free(struct mailimf_optional_field * opt_field);
3456 </programlisting>
3457
3458 <para>
3459 This is a non-standard header or unparsed header.
3460 </para>
3461
3462 <itemizedlist>
3463 <listitem>
3464 <para>
3465 <command>fld_name</command> is the name of the header
3466 field.
3467 </para>
3468 </listitem>
3469 <listitem>
3470 <para>
3471 <command>fld_value</command> is the value of the header
3472 field.
3473 </para>
3474 </listitem>
3475 </itemizedlist>
3476
3477 <para>
3478 <command>mailimf_optional_field_new()</command> This
3479 function creates and initializes a data structure with a
3480 value. Structures given as argument are referenced by the
3481 created object and will be freed if the object is released.
3482 </para>
3483
3484 <para>
3485 field name and field value have to be allocated with
3486 <command>malloc()</command>.
3487 </para>
3488
3489 <para>
3490 <command>mailimf_optional_field_free()</command> This
3491 function frees memory used by the structure and
3492 substructures will also be released.
3493 </para>
3494
3495 <example>
3496 <title>creation and display of non-standard fields</title>
3497 <programlisting role="C">
3498#include &lt;libetpan/libetpan.h&gt;
3499
3500int main(int argc, char ** argv)
3501{
3502 struct mailimf_optional_field * opt;
3503
3504 opt = mailimf_optional_field_new(strdup("X-My-Field"), strdup("my value"));
3505 /* do the things */
3506 mailimf_optional_field_free(opt);
3507
3508 return 0;
3509}
3510
3511/* display the optional field */
3512
3513#include &lt;libetpan/libetpan.h&gt;
3514#include &lt;stdio.h&gt;
3515
3516void display_optional_field(struct mailimf_optional_field * opt)
3517{
3518 printf("%s: %s\n", opt-&gt;fld_name, opt-&gt;fld_value);
3519}
3520 </programlisting>
3521 </example>
3522 </sect2>
3523
3524 <!-- mailimf_field -->
3525 <sect2 id="mailimf-field">
3526 <title>mailimf_field - header field</title>
3527
3528 <programlisting role="C">
3529#include &lt;libetpan/libetpan.h&gt;
3530
3531enum {
3532 MAILIMF_FIELD_NONE, /* on parse error */
3533 MAILIMF_FIELD_RETURN_PATH, /* Return-Path */
3534 MAILIMF_FIELD_RESENT_DATE, /* Resent-Date */
3535 MAILIMF_FIELD_RESENT_FROM, /* Resent-From */
3536 MAILIMF_FIELD_RESENT_SENDER, /* Resent-Sender */
3537 MAILIMF_FIELD_RESENT_TO, /* Resent-To */
3538 MAILIMF_FIELD_RESENT_CC, /* Resent-Cc */
3539 MAILIMF_FIELD_RESENT_BCC, /* Resent-Bcc */
3540 MAILIMF_FIELD_RESENT_MSG_ID, /* Resent-Message-ID */
3541 MAILIMF_FIELD_ORIG_DATE, /* Date */
3542 MAILIMF_FIELD_FROM, /* From */
3543 MAILIMF_FIELD_SENDER, /* Sender */
3544 MAILIMF_FIELD_REPLY_TO, /* Reply-To */
3545 MAILIMF_FIELD_TO, /* To */
3546 MAILIMF_FIELD_CC, /* Cc */
3547 MAILIMF_FIELD_BCC, /* Bcc */
3548 MAILIMF_FIELD_MESSAGE_ID, /* Message-ID */
3549 MAILIMF_FIELD_IN_REPLY_TO, /* In-Reply-To */
3550 MAILIMF_FIELD_REFERENCES, /* References */
3551 MAILIMF_FIELD_SUBJECT, /* Subject */
3552 MAILIMF_FIELD_COMMENTS, /* Comments */
3553 MAILIMF_FIELD_KEYWORDS, /* Keywords */
3554 MAILIMF_FIELD_OPTIONAL_FIELD, /* other field */
3555};
3556
3557struct mailimf_field {
3558 int fld_type;
3559 union {
3560 struct mailimf_return * fld_return_path; /* can be NULL */
3561 struct mailimf_orig_date * fld_resent_date; /* can be NULL */
3562 struct mailimf_from * fld_resent_from; /* can be NULL */
3563 struct mailimf_sender * fld_resent_sender; /* can be NULL */
3564 struct mailimf_to * fld_resent_to; /* can be NULL */
3565 struct mailimf_cc * fld_resent_cc; /* can be NULL */
3566 struct mailimf_bcc * fld_resent_bcc; /* can be NULL */
3567 struct mailimf_message_id * fld_resent_msg_id; /* can be NULL */
3568 struct mailimf_orig_date * fld_orig_date; /* can be NULL */
3569 struct mailimf_from * fld_from; /* can be NULL */
3570 struct mailimf_sender * fld_sender; /* can be NULL */
3571 struct mailimf_reply_to * fld_reply_to; /* can be NULL */
3572 struct mailimf_to * fld_to; /* can be NULL */
3573 struct mailimf_cc * fld_cc; /* can be NULL */
3574 struct mailimf_bcc * fld_bcc; /* can be NULL */
3575 struct mailimf_message_id * fld_message_id; /* can be NULL */
3576 struct mailimf_in_reply_to * fld_in_reply_to; /* can be NULL */
3577 struct mailimf_references * fld_references; /* can be NULL */
3578 struct mailimf_subject * fld_subject; /* can be NULL */
3579 struct mailimf_comments * fld_comments; /* can be NULL */
3580 struct mailimf_keywords * fld_keywords; /* can be NULL */
3581 struct mailimf_optional_field * fld_optional_field; /* can be NULL */
3582 } fld_data;
3583};
3584
3585struct mailimf_field *
3586mailimf_field_new(int fld_type,
3587 struct mailimf_return * fld_return_path,
3588 struct mailimf_orig_date * fld_resent_date,
3589 struct mailimf_from * fld_resent_from,
3590 struct mailimf_sender * fld_resent_sender,
3591 struct mailimf_to * fld_resent_to,
3592 struct mailimf_cc * fld_resent_cc,
3593 struct mailimf_bcc * fld_resent_bcc,
3594 struct mailimf_message_id * fld_resent_msg_id,
3595 struct mailimf_orig_date * fld_orig_date,
3596 struct mailimf_from * fld_from,
3597 struct mailimf_sender * fld_sender,
3598 struct mailimf_reply_to * fld_reply_to,
3599 struct mailimf_to * fld_to,
3600 struct mailimf_cc * fld_cc,
3601 struct mailimf_bcc * fld_bcc,
3602 struct mailimf_message_id * fld_message_id,
3603 struct mailimf_in_reply_to * fld_in_reply_to,
3604 struct mailimf_references * fld_references,
3605 struct mailimf_subject * fld_subject,
3606 struct mailimf_comments * fld_comments,
3607 struct mailimf_keywords * fld_keywords,
3608 struct mailimf_optional_field * fld_optional_field);
3609
3610void mailimf_field_free(struct mailimf_field * field);
3611 </programlisting>
3612
3613 <para>
3614 This is one header field of a message.
3615 </para>
3616
3617 <itemizedlist>
3618 <listitem>
3619 <para>
3620 <command>type</command> is the type of the field. This define the
3621 type of the field.
3622 Only the corresponding field should be, then,
3623 filled. The value of this field can be one of :
3624 <command>MAILIMF_FIELD_RETURN_PATH</command>,
3625 <command>MAILIMF_FIELD_RESENT_DATE</command>,
3626 <command>MAILIMF_FIELD_RESENT_FROM</command>,
3627 <command>MAILIMF_FIELD_RESENT_SENDER</command>,
3628 <command>MAILIMF_FIELD_RESENT_TO</command>,
3629 <command>MAILIMF_FIELD_RESENT_CC</command>,
3630 <command>MAILIMF_FIELD_RESENT_BCC</command>,
3631 <command>MAILIMF_FIELD_RESENT_MSG_ID</command>,
3632 <command>MAILIMF_FIELD_ORIG_DATE</command>,
3633 <command>MAILIMF_FIELD_FROM</command>,
3634 <command>MAILIMF_FIELD_SENDER</command>,
3635 <command>MAILIMF_FIELD_REPLY_TO</command>,
3636 <command>MAILIMF_FIELD_TO</command>,
3637 <command>MAILIMF_FIELD_CC</command>,
3638 <command>MAILIMF_FIELD_BCC</command>,
3639 <command>MAILIMF_FIELD_MESSAGE_ID</command>,
3640 <command>MAILIMF_FIELD_IN_REPLY_TO</command>,
3641 <command>MAILIMF_FIELD_REFERENCES</command>,
3642 <command>MAILIMF_FIELD_SUBJECT</command>,
3643 <command>MAILIMF_FIELD_COMMENTS</command>,
3644 <command>MAILIMF_FIELD_KEYWORDS</command>,
3645 <command>MAILIMF_FIELD_OPTIONAL_FIELD</command>.
3646 </para>
3647 </listitem>
3648 <listitem>
3649 <para>
3650 <command>fld_data.fld_return_path</command> is the
3651 parsed content of the Return-Path field
3652 if type is <command>MAILIMF_FIELD_RETURN_PATH</command>
3653 (see <xref linkend="mailimf-return">).
3654 </para>
3655 </listitem>
3656 <listitem>
3657 <para>
3658 <command>fld_data.fld_resent_date</command> is the
3659 parsed content of the Resent-Date field
3660 if type is <command>MAILIMF_FIELD_RESENT_DATE</command>
3661 (see <xref linkend="mailimf-orig-date">).
3662 </para>
3663 </listitem>
3664 <listitem>
3665 <para>
3666 <command>fld_data.fld_resent_from</command> is the
3667 parsed content of the Resent-From field
3668 if type is <command>MAILIMF_FIELD_RESENT_FROM</command>
3669 (see <xref linkend="mailimf-from">).
3670 </para>
3671 </listitem>
3672 <listitem>
3673 <para>
3674 <command>fld_data.fld_resent_sender</command> is the
3675 parsed content of the Resent-Sender field
3676 if type is <command>MAILIMF_FIELD_RESENT_SENDER</command>
3677 (see <xref linkend="mailimf-sender">).
3678 </para>
3679 </listitem>
3680 <listitem>
3681 <para>
3682 <command>fld_data.fld_resent_to</command> is the parsed
3683 content of the Resent-To field
3684 if type is <command>MAILIMF_FIELD_RESENT_TO</command>
3685 (see <xref linkend="mailimf-to">).
3686 </para>
3687 </listitem>
3688 <listitem>
3689 <para>
3690 <command>fld_data.fld_resent_cc</command> is the parsed
3691 content of the Resent-Cc field
3692 if type is <command>MAILIMF_FIELD_CC</command>
3693 (see <xref linkend="mailimf-cc">).
3694 </para>
3695 </listitem>
3696 <listitem>
3697 <para>
3698 <command>fld_data.fld_resent_bcc</command> is the parsed
3699 content of the Resent-Bcc field
3700 if type is <command>MAILIMF_FIELD_BCC</command>
3701 (see <xref linkend="mailimf-bcc">).
3702 </para>
3703 </listitem>
3704 <listitem>
3705 <para>
3706 <command>fld_data.fld_resent_msg_id</command> is the
3707 parsed content of the Resent-Message-ID field
3708 if type is <command>MAILIMF_FIELD_RESENT_MSG_ID</command>
3709 (see <xref linkend="mailimf-message-id">).
3710 </para>
3711 </listitem>
3712 <listitem>
3713 <para>
3714 <command>fld_data.fld_orig_date</command> is the parsed
3715 content of the Date field
3716 if type is <command>MAILIMF_FIELD_ORIG_DATE</command>
3717 (see <xref linkend="mailimf-orig-date">).
3718 </para>
3719 </listitem>
3720 <listitem>
3721 <para>
3722 <command>fld_data.fld_from</command> is the parsed
3723 content of the From field
3724 if type is <command>MAILIMF_FIELD_FROM</command>
3725 (see <xref linkend="mailimf-from">).
3726 </para>
3727 </listitem>
3728 <listitem>
3729 <para>
3730 <command>fld_data.fld_sender</command> is the parsed
3731 content of the Sender field
3732 if type is <command>MAILIMF_FIELD_SENDER</command>
3733 (see <xref linkend="mailimf-sender">).
3734 </para>
3735 </listitem>
3736 <listitem>
3737 <para>
3738 <command>fld_data.fld_reply_to</command> is the parsed
3739 content of the Reply-To field
3740 if type is <command>MAILIMF_FIELD_REPLY_TO</command>
3741 (see <xref linkend="mailimf-reply-to">).
3742 </para>
3743 </listitem>
3744 <listitem>
3745 <para>
3746 <command>fld_data.fld_to</command> is the parsed content
3747 of the To field if type is
3748 <command>MAILIMF_FIELD_TO</command>
3749 (see <xref linkend="mailimf-to">).
3750 </para>
3751 </listitem>
3752 <listitem>
3753 <para>
3754 <command>fld_data.fld_cc</command> is the parsed content
3755 of the Cc field if type is
3756 <command>MAILIMF_FIELD_CC</command>
3757 (see <xref linkend="mailimf-cc">).
3758 </para>
3759 </listitem>
3760 <listitem>
3761 <para>
3762 <command>fld_data.fld_bcc</command> is the parsed
3763 content of the Bcc field if type is
3764 <command>MAILIMF_FIELD_BCC</command>
3765 (see <xref linkend="mailimf-bcc">).
3766 </para>
3767 </listitem>
3768 <listitem>
3769 <para>
3770 <command>fld_data.fld_message_id</command> is the parsed
3771 content of the Message-ID field
3772 if type is <command>MAILIMF_FIELD_MESSAGE_ID</command>
3773 (see <xref linkend="mailimf-message-id">).
3774 </para>
3775 </listitem>
3776 <listitem>
3777 <para>
3778 <command>fld_data.fld_in_reply_to</command> is the
3779 parsed content of the In-Reply-To field
3780 if type is <command>MAILIMF_FIELD_IN_REPLY_TO</command>
3781 (see <xref linkend="mailimf-in-reply-to">).
3782 </para>
3783 </listitem>
3784 <listitem>
3785 <para>
3786 <command>fld_data.fld_references</command> is the parsed
3787 content of the References field
3788 if type is <command>MAILIMF_FIELD_REFERENCES</command>
3789 (see <xref linkend="mailimf-references">).
3790 </para>
3791 </listitem>
3792 <listitem>
3793 <para>
3794 <command>fld_data.fld_subject</command> is the content
3795 of the Subject field
3796 if type is <command>MAILIMF_FIELD_SUBJECT</command>
3797 (see <xref linkend="mailimf-subject">).
3798 </para>
3799 </listitem>
3800 <listitem>
3801 <para>
3802 <command>fld_data.fld_comments</command> is the content of the
3803 Comments field
3804 if type is <command>MAILIMF_FIELD_COMMENTS</command>
3805 (see <xref linkend="mailimf-comments">).
3806 </para>
3807 </listitem>
3808 <listitem>
3809 <para>
3810 <command>fld_data.fld_keywords</command> is the parsed
3811 content of the Keywords field
3812 if type is <command>MAILIMF_FIELD_KEYWORDS</command>
3813 (see <xref linkend="mailimf-keywords">).
3814 </para>
3815 </listitem>
3816 <listitem>
3817 <para>
3818 <command>fld_data.fld_optional_field</command> is an
3819 other field and is not parsed
3820 if type is <command>MAILIMF_FIELD_OPTIONAL_FIELD</command>
3821 (see <xref linkend="mailimf-optional-field">).
3822 </para>
3823 </listitem>
3824 </itemizedlist>
3825
3826 <para>
3827 <command>mailimf_field_new()</command> creates and
3828 initializes a data structure with a value.
3829 Structures given as argument are referenced by the created
3830 object and will be freed if the object is released.
3831 </para>
3832
3833 <para>
3834 <command>mailimf_field_free()</command> frees memory used by
3835 the structure and substructures will also be released.
3836 </para>
3837
3838 <example>
3839 <title>creation and display of field</title>
3840 <programlisting role="C">
3841#include &lt;libetpan/libetpan.h&gt;
3842
3843int main(int argc, char ** argv)
3844{
3845 struct mailimf_field * f;
3846 struct mailimf_mailbox * mb;
3847 struct mailimf_mailbox_list * mb_list;
3848 struct mailimf_from * from;
3849
3850 /* build header 'From' */
3851
3852 list = clist_new();
3853 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
3854 strdup("dinh.viet.hoa@free.fr"));
3855 clist_append(list, mb);
3856 mb_list = mailimf_mailbox_list_new(list);
3857
3858 from = mailimf_from_new(mb_list);
3859
3860 f = mailimf_field_new(MAILIMF_FIELD_FROM,
3861 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
3862 from, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
3863 NULL, NULL, NULL, NULL);
3864 /* do the things */
3865 mailimf_field_free(f);
3866
3867 return 0;
3868}
3869
3870/* display content of the header */
3871
3872#include &lt;libetpan/libetpan.h&gt;
3873#include &lt;stdio.h&gt;
3874
3875void display_field(struct mailimf_field * field)
3876{
3877 switch (field-&gt;type) {
3878 case MAILIMF_FIELD_RETURN_PATH:
3879 printf("Return-Path:\n");
3880 display_return(field-&gt;fld_data.fld_return_path);
3881 break;
3882 case MAILIMF_FIELD_RESENT_DATE:
3883 printf("Resent-Date:\n");
3884 display_orig_date(field-&gt;fld_data.fld_orig_date);
3885 break;
3886 case MAILIMF_FIELD_RESENT_FROM:
3887 printf("Resent-From:\n");
3888 display_from(field-&gt;fld_data.fld_orig_date);
3889 break;
3890 case MAILIMF_FIELD_RESENT_SENDER:
3891 printf("Resent-Sender:\n");
3892 display_sender(field-&gt;fld_data.fld_resent_sender);
3893 break;
3894 case MAILIMF_FIELD_RESENT_TO:
3895 printf("Resent-To:\n");
3896 display_to(field-&gt;fld_data.fld_resent_to);
3897 break;
3898 case MAILIMF_FIELD_RESENT_CC:
3899 printf("Resent-Cc:\n");
3900 display_from(field-&gt;fld_data.fld_resent_cc);
3901 break;
3902 case MAILIMF_FIELD_RESENT_BCC:
3903 printf("Resent-Bcc:\n");
3904 display_from(field-&gt;fld_data.fld_resent_bcc);
3905 break;
3906 case MAILIMF_FIELD_RESENT_MSG_ID:
3907 printf("Resent-Message-ID:\n");
3908 display_message_id(field-&gt;fld_data.fld_resent_msg_id);
3909 break;
3910 case MAILIMF_FIELD_ORIG_DATE:
3911 printf("Date:\n");
3912 display_orig_date(field-&gt;fld_data.fld_orig_date);
3913 break;
3914 case MAILIMF_FIELD_FROM:
3915 printf("From:\n");
3916 display_from(field-&gt;fld_data.fld_from);
3917 break;
3918 case MAILIMF_FIELD_SENDER:
3919 printf("Sender:\n");
3920 display_sender(field-&gt;fld_data.fld_sender);
3921 break;
3922 case MAILIMF_FIELD_REPLY_TO:
3923 printf("Reply-To:\n");
3924 display_reply_to(field-&gt;fld_data.fld_reply_to);
3925 break;
3926 case MAILIMF_FIELD_TO:
3927 printf("To:\n");
3928 display_to(field-&gt;fld_data.fld_to);
3929 break;
3930 case MAILIMF_FIELD_CC:
3931 printf("Cc:\n");
3932 display_cc(field-&gt;fld_data.fld_cc);
3933 break;
3934 case MAILIMF_FIELD_BCC:
3935 printf("Bcc:\n");
3936 display_bcc(field-&gt;fld_data.fld_bcc);
3937 break;
3938 case MAILIMF_FIELD_MESSAGE_ID:
3939 printf("Message-ID:\n");
3940 display_message_id(field-&gt;fld_data.fld_message_id);
3941 break;
3942 case MAILIMF_FIELD_IN_REPLY_TO:
3943 printf("In-Reply-To:\n");
3944 display_in_reply_to(field-&gt;fld_data.fld_in_reply_to);
3945 break;
3946 case MAILIMF_FIELD_REFERENCES:
3947 printf("References:\n");
3948 display_references(field-&gt;fld_data.fld_references_to);
3949 break;
3950 case MAILIMF_FIELD_SUBJECT:
3951 printf("Subject:\n");
3952 display_subject(field-&gt;fld_data.fld_subject);
3953 break;
3954 case MAILIMF_FIELD_COMMENTS:
3955 printf("Comments:\n");
3956 display_comments(field-&gt;fld_data.fld_comments);
3957 break;
3958 case MAILIMF_FIELD_KEYWORDS:
3959 printf("Keywords:\n");
3960 display_keywords(field-&gt;fld_data.fld_keywords);
3961 break;
3962 case MAILIMF_FIELD_OPTIONAL_FIELD:
3963 printf("[optional field]:\n");
3964 display_optional_field(field-&gt;fld_data.fld_optional_field);
3965 break;
3966 }
3967}
3968 </programlisting>
3969 </example>
3970 </sect2>
3971
3972 <!-- mailimf_fields -->
3973 <sect2 id="mailimf-fields">
3974 <title>mailimf_fields - list of header fields</title>
3975
3976 <programlisting role="C">
3977#include &lt;libetpan/libetpan.h&gt;
3978
3979struct mailimf_fields {
3980 clist * fld_list; /* list of (struct mailimf_field *), != NULL */
3981};
3982
3983struct mailimf_fields * mailimf_fields_new(clist * fld_list);
3984
3985void mailimf_fields_free(struct mailimf_fields * fields);
3986 </programlisting>
3987
3988 <para>
3989 This is the list of header fields of a message.
3990 </para>
3991
3992 <para>
3993 <command>fld_list</command> is a list of header fields. This
3994 is a <command>clist</command> which elements are
3995 of type <command>mailimf_field</command> (see <xref
3996 linkend="mailimf-field">).
3997 </para>
3998
3999 <para>
4000 <command>mailimf_fields_new()</command> creates and
4001 initializes a data structure with a value.
4002 Structures given as argument are referenced by the created
4003 object and will be freed if the object is released.
4004 </para>
4005
4006 <para>
4007 <command>mailimf_fields_free()</command> frees memory used
4008 by the structure and substructures will also be released.
4009 </para>
4010
4011 <example>
4012 <title>creation and display of header fields</title>
4013 <programlisting role="C">
4014#include &lt;libetpan/libetpan.h&gt;
4015
4016int main(int argc, char ** argv)
4017{
4018 struct mailimf_fields * fields;
4019 struct mailimf_field * f;
4020 clist * list;
4021 struct mailimf_from * from;
4022 struct mailimf_to * to
4023 struct mailimf_mailbox * mb;
4024 struct mailimf_address * addr;
4025 struct mailimf_mailbox_list * mb_list;
4026 struct mailimf_address_list * addr_list;
4027 clist * fields_list;
4028
4029 /* build headers */
4030
4031 fields_list = clist_new();
4032
4033 /* build header 'From' */
4034
4035 list = clist_new();
4036 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
4037 strdup("dinh.viet.hoa@free.fr"));
4038 clist_append(list, mb);
4039 mb_list = mailimf_mailbox_list_new(list);
4040
4041 from = mailimf_from_new(mb_list);
4042
4043 f = mailimf_field_new(MAILIMF_FIELD_FROM,
4044 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4045 from, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4046 NULL, NULL, NULL, NULL);
4047
4048 clist_append(fields_list, f);
4049
4050 /* build header To */
4051
4052 list = clist_new();
4053 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
4054 strdup("dinh.viet.hoa@free.fr"));
4055 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
4056 clist_append(list, addr);
4057 addr_list = mailimf_address_list_new(list);
4058
4059 to = mailimf_to_new(addr_list);
4060
4061 f = mailimf_field_new(MAILIMF_FIELD_TO,
4062 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4063 NULL, NULL, NULL, to, NULL, NULL, NULL, NULL, NULL,
4064 NULL, NULL, NULL, NULL);
4065
4066 clist_append(fields_list, f);
4067
4068 fields = mailimf_fields_new(fields_list);
4069 /* do the things */
4070 mailimf_fields_free(fields);
4071
4072 return 0;
4073}
4074
4075/* display list of headers */
4076
4077#include &lt;libetpan/libetpan.h&gt;
4078#include &lt;stdio.h&gt;
4079
4080void display_fields(struct mailimf_fields * fields)
4081{
4082 clistiter * cur;
4083
4084 for(cur = clist_begin(field-&gt;fld_list) ; cur != NULL ;
4085 cur = clist_next(cur)) {
4086 struct mailimf_field * f;
4087
4088 f = clist_content(cur);
4089
4090 display_field(f);
4091 printf("\n");
4092 }
4093}
4094 </programlisting>
4095 </example>
4096 </sect2>
4097
4098 <!-- mailimf_body -->
4099 <sect2 id="mailimf-body">
4100 <title>mailimf_body - message body without headers</title>
4101
4102 <programlisting role="C">
4103#include &lt;libetpan/libetpan.h&gt;
4104
4105struct mailimf_body {
4106 const char * bd_text; /* != NULL */
4107 size_t bd_size;
4108};
4109
4110struct mailimf_body * mailimf_body_new(const char * bd_text, size_t bd_size);
4111
4112void mailimf_body_free(struct mailimf_body * body);
4113 </programlisting>
4114
4115 <para>
4116 This is the text content of a message (without headers).
4117 </para>
4118 <para>
4119 <itemizedlist>
4120 <listitem>
4121 <para>
4122 <command>bd_text</command> is the beginning of the
4123 text part, it is a substring of an other string.
4124 It is not necessarily zero terminated.
4125 </para>
4126 </listitem>
4127 <listitem>
4128 <para>
4129 <command>bd_size</command> is the size of the text part
4130 </para>
4131 </listitem>
4132 </itemizedlist>
4133 </para>
4134
4135 <para>
4136 <command>mailimf_body_new()</command> creates and
4137 initializes a data structure with a value.
4138 Text given as argument will <emphasis>NOT</emphasis> be released.
4139 </para>
4140
4141 <para>
4142 <command>mailimf_body_free()</command> frees memory used by
4143 the structure.
4144 </para>
4145
4146 <example>
4147 <title>creation and display of message body</title>
4148 <programlisting role="C">
4149#include &lt;libetpan/libetpan.h&gt;
4150
4151int main(int argc, char ** argv)
4152{
4153 struct mailimf_body * b;
4154
4155 b = mailimf_body_new("this is the content of the message", 34);
4156 /* do the things */
4157 mailimf_body_free(b);
4158
4159 return 0;
4160}
4161
4162#include &lt;libetpan/libetpan.h&gt;
4163#include &lt;stdio.h&gt;
4164
4165void display_body(struct mailimf_body * b)
4166{
4167 char * text;
4168
4169 text = malloc(b-&gt;size + 1);
4170 strncpy(text, b-&gt;bd_text, b-&gt;bd_size);
4171 text[b-&gt;size] = 0;
4172
4173 puts(text);
4174 printf("\n");
4175
4176 free(text);
4177
4178 return 0;
4179}
4180 </programlisting>
4181 </example>
4182 </sect2>
4183
4184 <!-- mailimf_message -->
4185 <sect2 id="mailimf-message">
4186 <title>mailimf_message - parsed message</title>
4187
4188 <programlisting role="C">
4189#include &lt;libetpan/libetpan.h&gt;
4190
4191struct mailimf_message {
4192 struct mailimf_fields * msg_fields; /* != NULL */
4193 struct mailimf_body * msg_body; /* != NULL */
4194};
4195
4196struct mailimf_message *
4197mailimf_message_new(struct mailimf_fields * msg_fields,
4198 struct mailimf_body * msg_body);
4199
4200void mailimf_message_free(struct mailimf_message * message);
4201 </programlisting>
4202
4203 <para>
4204 This is the message content (text and headers).
4205 </para>
4206
4207 <itemizedlist>
4208 <listitem>
4209 <para>
4210 <command>msg_fields</command> is the header fields of
4211 the message
4212 (see <xref linkend="mailimf-fields">).
4213 </para>
4214 </listitem>
4215 <listitem>
4216 <para>
4217 <command>msg_body</command> is the text part of the message
4218 (see <xref linkend="mailimf-body">).
4219 </para>
4220 </listitem>
4221 </itemizedlist>
4222
4223 <para>
4224 <command>mailimf_message_new()</command> creates and
4225 initializes a data structure with a value.
4226 Structures given as argument are referenced by the created
4227 object and will be freed if the object is released.
4228 </para>
4229
4230 <para>
4231 <command>mailimf_message_free()</command> frees memory used
4232 by the structure and substructures will also be released.
4233 </para>
4234
4235 <example>
4236 <title>creation and display of message</title>
4237 <programlisting>
4238#include &lt;libetpan/libetpan.h&gt;
4239
4240int main(int argc, char ** argv)
4241{
4242 struct mailimf_body * b;
4243 struct mailimf_message * m;
4244 struct mailimf_fields * fields;
4245 struct mailimf_fields * f;
4246 clist * list;
4247 struct mailimf_from * from;
4248 struct mailimf_to * to
4249 struct mailimf_mailbox * mb;
4250 struct mailimf_address * addr;
4251 struct mailimf_mailbox_list * mb_list;
4252 struct mailimf_address_list * addr_list;
4253 clist * fields_list;
4254
4255 /* build text content */
4256
4257 b = mailimf_body_new("this is the content of the message", 34);
4258
4259 /* build headers */
4260
4261 fields_list = clist_new();
4262
4263 /* build header 'From' */
4264
4265 list = clist_new();
4266 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
4267 strdup("dinh.viet.hoa@free.fr"));
4268 clist_append(list, mb);
4269 mb_list = mailimf_mailbox_list_new(list);
4270
4271 from = mailimf_from_new(mb_list);
4272
4273 f = mailimf_field_new(MAILIMF_FIELD_FROM,
4274 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4275 from, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4276 NULL, NULL, NULL, NULL);
4277
4278 clist_append(fields_list, f);
4279
4280 /* build header To */
4281
4282 list = clist_new();
4283 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
4284 strdup("dinh.viet.hoa@free.fr"));
4285 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
4286 clist_append(list, addr);
4287 addr_list = mailimf_address_list_new(list);
4288
4289 to = mailimf_to_new(addr_list);
4290
4291 f = mailimf_field_new(MAILIMF_FIELD_TO,
4292 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4293 NULL, NULL, NULL, to, NULL, NULL, NULL, NULL, NULL,
4294 NULL, NULL, NULL, NULL);
4295
4296 clist_append(fields_list, f);
4297
4298 fields = mailimf_fields_new(fields_list);
4299
4300 /* build message */
4301
4302 m = mailimf_message_new(fields, b);
4303 /* do the things */
4304 mailimf_message_free(m);
4305
4306 return 0;
4307}
4308
4309/* display the message */
4310
4311#include &lt;libetpan/libetpan.h&gt;
4312#include &lt;stdio.h&gt;
4313
4314void display_message(struct mailimf_message * msg)
4315{
4316 display_fields(msg-&gt;msg_fields);
4317 printf("\n");
4318 display_body(msg-&gt;msg_body);
4319 printf("\n");
4320}
4321 </programlisting>
4322 </example>
4323 </sect2>
4324
4325 <!-- mailimf_single_fields -->
4326 <sect2 id="mailimf-single-fields">
4327 <title>mailimf_single_fields - simplified fields</title>
4328
4329<programlisting role="C">
4330#include &lt;libetpan/libetpan.h&gt;
4331
4332struct mailimf_single_fields {
4333 struct mailimf_orig_date * fld_orig_date; /* can be NULL */
4334 struct mailimf_from * fld_from; /* can be NULL */
4335 struct mailimf_sender * fld_sender; /* can be NULL */
4336 struct mailimf_reply_to * fld_reply_to; /* can be NULL */
4337 struct mailimf_to * fld_to; /* can be NULL */
4338 struct mailimf_cc * fld_cc; /* can be NULL */
4339 struct mailimf_bcc * fld_bcc; /* can be NULL */
4340 struct mailimf_message_id * fld_message_id; /* can be NULL */
4341 struct mailimf_in_reply_to * fld_in_reply_to; /* can be NULL */
4342 struct mailimf_references * fld_references; /* can be NULL */
4343 struct mailimf_subject * fld_subject; /* can be NULL */
4344 struct mailimf_comments * fld_comments; /* can be NULL */
4345 struct mailimf_keywords * fld_keywords; /* can be NULL */
4346};
4347
4348struct mailimf_single_fields *
4349mailimf_single_fields_new(struct mailimf_fields * fields);
4350
4351void mailimf_single_fields_free(struct mailimf_single_fields *
4352 single_fields);
4353
4354void mailimf_single_fields_init(struct mailimf_single_fields * single_fields,
4355 struct mailimf_fields * fields);
4356</programlisting>
4357
4358 <para>
4359 Structure that contains some standard fields and allows access
4360 to a given header without running through the list.
4361 </para>
4362
4363 <para>
4364 mailimf_fields is the native structure that IMF module will use,
4365 this module will provide an easier structure to use when
4366 parsing fields.
4367 mailimf_single_fields is an easier structure to get parsed fields,
4368 rather than iteration over the list of fields
4369 </para>
4370
4371 <itemizedlist>
4372 <listitem>
4373 <para>
4374 <command>fld_orig_date</command> is the parsed "Date"
4375 field
4376 (see <xref linkend="mailimf-orig-date">).
4377 </para>
4378 </listitem>
4379 <listitem>
4380 <para>
4381 <command>fld_from</command> is the parsed "From" field
4382 (see <xref linkend="mailimf-from">).
4383 </para>
4384 </listitem>
4385 <listitem>
4386 <para>
4387 <command>fld_sender</command> is the parsed "Sender "field
4388 (see <xref linkend="mailimf-sender">).
4389 </para>
4390 </listitem>
4391 <listitem>
4392 <para>
4393 <command>reply_to</command> is the parsed "Reply-To" field
4394 (see <xref linkend="mailimf-reply-to">).
4395 </para>
4396 </listitem>
4397 <listitem>
4398 <para>
4399 <command>fld_to</command> is the parsed "To" field
4400 (see <xref linkend="mailimf-to">).
4401 </para>
4402 </listitem>
4403 <listitem>
4404 <para>
4405 <command>fld_cc</command> is the parsed "Cc" field
4406 (see <xref linkend="mailimf-cc">).
4407 </para>
4408 </listitem>
4409 <listitem>
4410 <para>
4411 <command>fld_bcc</command> is the parsed "Bcc" field
4412 (see <xref linkend="mailimf-bcc">).
4413 </para>
4414 </listitem>
4415 <listitem>
4416 <para>
4417 <command>fld_message_id</command> is the parsed
4418 "Message-ID" field.
4419 (see <xref linkend="mailimf-message-id">).
4420 </para>
4421 </listitem>
4422 <listitem>
4423 <para>
4424 <command>fld_in_reply_to</command> is the parsed
4425 "In-Reply-To" field.
4426 (see <xref linkend="mailimf-in-reply-to">).
4427 </para>
4428 </listitem>
4429 <listitem>
4430 <para>
4431 <command>fld_references</command> is the parsed
4432 "References" field.
4433 (see <xref linkend="mailimf-references">).
4434 </para>
4435 </listitem>
4436 <listitem>
4437 <para>
4438 <command>fld_subject</command> is the parsed "Subject" field
4439 (see <xref linkend="mailimf-subject">).
4440 </para>
4441 </listitem>
4442 <listitem>
4443 <para>
4444 <command>fld_comments</command> is the parsed "Comments" field
4445 (see <xref linkend="mailimf-comments">).
4446 </para>
4447 </listitem>
4448 <listitem>
4449 <para>
4450 <command>fld_keywords</command> is the parsed "Keywords" field
4451 (see <xref linkend="mailimf-keywords">).
4452 </para>
4453 </listitem>
4454 </itemizedlist>
4455
4456 <para>
4457 <command>mailimf_single_fields_new()</command> creates and
4458 initializes a data structure with a value.
4459 Structures given as argument are referenced by the created
4460 object and will <emphasis>NOT</emphasis> be freed if the
4461 object is released.
4462 </para>
4463
4464 <para>
4465 <command>mailimf_single_fields_free()</command> frees memory
4466 used by the structure and
4467 substructures will <emphasis>NOT</emphasis> be
4468 released. They should be released by the application.
4469 </para>
4470
4471 <para>
4472 <command>mailimf_single_fields_init()</command> will
4473 initialize fill the data structure, using
4474 the given argument (<command>fields</command>). The
4475 interesting fields will be filled into
4476 <command>single_fields</command>.
4477 </para>
4478
4479 <example>
4480 <title>using mailimf_single_fields</title>
4481 <programlisting role="C">
4482#include &lt;libetpan/libetpan.h&gt;
4483
4484int main(int argc, char ** argv)
4485{
4486 struct mailimf_single_fields * single_fields;
4487 struct mailimf_fields * fields;
4488 struct mailimf_field * f;
4489 clist * list;
4490 struct mailimf_from * from;
4491 struct mailimf_to * to
4492 struct mailimf_mailbox * mb;
4493 struct mailimf_address * addr;
4494 struct mailimf_mailbox_list * mb_list;
4495 struct mailimf_address_list * addr_list;
4496 clist * fields_list;
4497
4498 /* build headers */
4499
4500 fields_list = clist_new();
4501
4502 /* build header 'From' */
4503
4504 list = clist_new();
4505 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
4506 strdup("dinh.viet.hoa@free.fr"));
4507 clist_append(list, mb);
4508 mb_list = mailimf_mailbox_list_new(list);
4509
4510 from = mailimf_from_new(mb_list);
4511
4512 f = mailimf_field_new(MAILIMF_FIELD_FROM,
4513 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4514 from, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4515 NULL, NULL, NULL, NULL);
4516
4517 clist_append(fields_list, f);
4518
4519 /* build header To */
4520
4521 list = clist_new();
4522 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
4523 strdup("dinh.viet.hoa@free.fr"));
4524 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
4525 clist_append(list, addr);
4526 addr_list = mailimf_address_list_new(list);
4527
4528 to = mailimf_to_new(addr_list);
4529
4530 f = mailimf_field_new(MAILIMF_FIELD_TO,
4531 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4532 NULL, NULL, NULL, to, NULL, NULL, NULL, NULL, NULL,
4533 NULL, NULL, NULL, NULL);
4534
4535 clist_append(fields_list, f);
4536
4537 fields = mailimf_fields_new(fields_list);
4538
4539 /* create the single fields */
4540 single_fields = mailimf_single_fields_new(fields);
4541 /* do the things */
4542 mailimf_single_fields_free(single_fields);
4543 mailimf_fields_free(fields);
4544
4545 return 0;
4546}
4547 </programlisting>
4548 </example>
4549
4550 <example>
4551 <title>using mailimf_single_fields without memory allocation</title>
4552 <programlisting>
4553#include &lt;libetpan/libetpan.h&gt;
4554
4555int main(int argc, char ** argv)
4556{
4557 struct mailimf_single_fields single_fields;
4558 struct mailimf_fields * fields;
4559 struct mailimf_field * f;
4560 clist * list;
4561 struct mailimf_from * from;
4562 struct mailimf_to * to
4563 struct mailimf_mailbox * mb;
4564 struct mailimf_address * addr;
4565 struct mailimf_mailbox_list * mb_list;
4566 struct mailimf_address_list * addr_list;
4567 clist * fields_list;
4568
4569 /* build headers */
4570
4571 fields_list = clist_new();
4572
4573 /* build header 'From' */
4574
4575 list = clist_new();
4576 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
4577 strdup("dinh.viet.hoa@free.fr"));
4578 clist_append(list, mb);
4579 mb_list = mailimf_mailbox_list_new(list);
4580
4581 from = mailimf_from_new(mb_list);
4582
4583 f = mailimf_field_new(MAILIMF_FIELD_FROM,
4584 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4585 from, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4586 NULL, NULL, NULL, NULL);
4587
4588 clist_append(fields_list, f);
4589
4590 /* build header To */
4591
4592 list = clist_new();
4593 mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
4594 strdup("dinh.viet.hoa@free.fr"));
4595 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
4596 clist_append(list, addr);
4597 addr_list = mailimf_address_list_new(list);
4598
4599 to = mailimf_to_new(addr_list);
4600
4601 f = mailimf_field_new(MAILIMF_FIELD_TO,
4602 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4603 NULL, NULL, NULL, to, NULL, NULL, NULL, NULL, NULL,
4604 NULL, NULL, NULL, NULL);
4605
4606 clist_append(fields_list, f);
4607
4608 fields = mailimf_fields_new(fields_list);
4609
4610 /* fill the single fields */
4611 mailimf_fields_fields_init(&amp;single_fields, fields);
4612 /* do the things */
4613 mailimf_fields_free(fields);
4614
4615 return 0;
4616}
4617 </programlisting>
4618 </example>
4619 </sect2>
4620 </sect1>
4621
4622 <!-- parser functions -->
4623 <sect1>
4624 <title>Parser functions</title>
4625
4626 <!-- mailimf_address_list_parse -->
4627 <sect2 id="mailimf-address-list-parse">
4628 <title>mailimf_address_list_parse</title>
4629 <programlisting role="C">
4630int
4631mailimf_address_list_parse(char * message, size_t length,
4632 size_t * index,
4633 struct mailimf_address_list ** result);
4634 </programlisting>
4635
4636 <para>
4637 <command>mailimf_address_list_parse()</command> parse a list
4638 of addresses in RFC 2822 form.
4639 </para>
4640
4641 <itemizedlist>
4642 <listitem>
4643 <para>
4644 <command>message</command> this is a string containing
4645 the list of addresses.
4646 </para>
4647 </listitem>
4648 <listitem>
4649 <para>
4650 <command>length</command> this is the size of the given string
4651 </para>
4652 </listitem>
4653 <listitem>
4654 <para>
4655 <command>index</command> this is a pointer to the
4656 start of the list of
4657 addresses in the given string,
4658 <command>(* index)</command> is modified to point
4659 at the end of the parsed data.
4660 </para>
4661 </listitem>
4662 <listitem>
4663 <para>
4664 <command>result</command> the result of the parse
4665 operation is stored in
4666 <command>(* result)</command>
4667 (see <xref linkend="mailimf-address-list">).
4668 </para>
4669 </listitem>
4670 </itemizedlist>
4671
4672 <para>
4673 return <command>MAILIMF_NO_ERROR</command> on success,
4674 <command>MAILIMF_ERROR_XXX</command> on error.
4675 </para>
4676
4677 <example>
4678 <title>parsing a list of addresses</title>
4679 <programlisting role="C">
4680#include &lt;libetpan/libetpan.h&gt;
4681#include &lt;sys/stat.h&gt;
4682#include &lt;sys/mman.h&gt;
4683
4684int main(int argc, char ** argv)
4685{
4686 int fd;
4687 int r;
4688
4689 status = EXIT_FAILURE;
4690
4691 fd = open("message.rfc2822", O_RDONLY);
4692 if (fd >= 0) {
4693 void * mem;
4694 struct stat stat_info;
4695
4696 r = fstat(fd, &amp;stat_info);
4697 if (r >= 0) {
4698 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
4699 if (mem != MAP_FAILED) {
4700 struct mailimf_address_list * addr_list;
4701 size_t current_index;
4702
4703 current_index = 0;
4704 r = mailimf_address_list_parse(mem, stat_info.st_size,
4705 &amp;current_index, &amp;addr_list);
4706 if (r == MAILIMF_NO_ERROR) {
4707 display_address_list(addr_list);
4708 /* do the things */
4709 status = EXIT_SUCCESS;
4710 mailimf_address_list_free(addr_list);
4711 }
4712 }
4713 munmap(mem, stat_info.st_size);
4714 }
4715
4716 close(fd);
4717 }
4718
4719 exit(status);
4720}
4721 </programlisting>
4722 </example>
4723 </sect2>
4724
4725 <!-- mailimf_address_parse -->
4726 <sect2 id="mailimf-address-parse">
4727 <title>mailimf_address_parse</title>
4728
4729 <programlisting role="C">
4730#include &lt;libetpan/libetpan.h&gt;
4731
4732int
4733mailimf_address_parse(char * message, size_t length,
4734 size_t * index,
4735 struct mailimf_address ** result);
4736 </programlisting>
4737
4738 <para>
4739 <command>mailimf_address_parse()</command> parse an address
4740 in RFC 2822 form.
4741 </para>
4742
4743 <itemizedlist>
4744 <listitem>
4745 <para>
4746 <command>message</command> this is a string containing the
4747 address.
4748 </para>
4749 </listitem>
4750 <listitem>
4751 <para>
4752 <command>length</command> this is the size of the given
4753 string.
4754 </para>
4755 </listitem>
4756 <listitem>
4757 <para>
4758 <command>index</command> index this is a pointer to the
4759 start of the address in the given string, <command>(*
4760 index)</command> is modified to point at the end of the
4761 parsed data.
4762 </para>
4763 </listitem>
4764 <listitem>
4765 <para>
4766 <command>result</command> the result of the parse operation
4767 is stored in <command>(* result)</command>
4768 (see <xref linkend="mailimf-address">).
4769 </para>
4770 </listitem>
4771 </itemizedlist>
4772
4773 <para>
4774 return <command>MAILIMF_NO_ERROR</command> on success,
4775 <command>MAILIMF_ERROR_XXX</command> on error.
4776 </para>
4777
4778 <example>
4779 <title>parsing an address</title>
4780 <programlisting role="C">
4781#include &lt;libetpan/libetpan.h&gt;
4782#include &lt;sys/stat.h&gt;
4783#include &lt;sys/mman.h&gt;
4784
4785int main(int argc, char ** argv)
4786{
4787 int fd;
4788 int r;
4789
4790 status = EXIT_FAILURE;
4791
4792 fd = open("message.rfc2822", O_RDONLY);
4793 if (fd >= 0) {
4794 void * mem;
4795 struct stat stat_info;
4796
4797 r = fstat(fd, &amp;stat_info);
4798 if (r >= 0) {
4799 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
4800 if (mem != MAP_FAILED) {
4801 struct mailimf_address * addr;
4802 size_t current_index;
4803
4804 current_index = 0;
4805 r = mailimf_address_parse(mem, stat_info.st_size,
4806 &amp;current_index, &amp;addr);
4807 if (r == MAILIMF_NO_ERROR) {
4808 display_address(addr);
4809 /* do the things */
4810 status = EXIT_SUCCESS;
4811 mailimf_address_free(addr);
4812 }
4813 }
4814 munmap(mem, stat_info.st_size);
4815 }
4816
4817 close(fd);
4818 }
4819
4820 exit(status);
4821}
4822 </programlisting>
4823 </example>
4824
4825 </sect2>
4826
4827 <!-- mailimf_body_parse -->
4828 <sect2 id="mailimf-body-parse">
4829 <title>mailimf_body_parse</title>
4830
4831 <programlisting role="C">
4832#include &lt;libetpan/libetpan.h&gt;
4833
4834int mailimf_body_parse(char * message, size_t length,
4835 size_t * index,
4836 struct mailimf_body ** result);
4837 </programlisting>
4838
4839 <para>
4840 <command>mailimf_body_parse()</command> parse text body of a
4841 message.
4842 </para>
4843
4844 <itemizedlist>
4845 <listitem>
4846 <para>
4847 <command>message</command> this is a string containing
4848 the message body part.
4849 </para>
4850 </listitem>
4851 <listitem>
4852 <para>
4853 <command>length</command> this is the size of the given
4854 string.
4855 </para>
4856 </listitem>
4857 <listitem>
4858 <para>
4859 <command>index</command> this is a pointer to the start
4860 of the message text part in
4861 the given string, <command>(* index)</command> is
4862 modified to point at the end
4863 of the parsed data.
4864 </para>
4865 </listitem>
4866 <listitem>
4867 <para>
4868 <command>result</command> the result of the parse
4869 operation is stored in
4870 <command>(* result)</command>
4871 (see <xref linkend="mailimf-body">).
4872 </para>
4873 </listitem>
4874 </itemizedlist>
4875
4876 <para>
4877 return <command>MAILIMF_NO_ERROR</command> on success,
4878 <command>MAILIMF_ERROR_XXX</command> on error.
4879 </para>
4880
4881 <example>
4882 <title>parsing a message body</title>
4883 <programlisting role="C">
4884#include &lt;libetpan/libetpan.h&gt;
4885#include &lt;sys/stat.h&gt;
4886#include &lt;sys/mman.h&gt;
4887
4888int main(int argc, char ** argv)
4889{
4890 int fd;
4891 int r;
4892
4893 status = EXIT_FAILURE;
4894
4895 fd = open("message.rfc2822", O_RDONLY);
4896 if (fd >= 0) {
4897 void * mem;
4898 struct stat stat_info;
4899
4900 r = fstat(fd, &amp;stat_info);
4901 if (r >= 0) {
4902 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
4903 if (mem != MAP_FAILED) {
4904 struct mailimf_body * b;
4905 struct mailimf_fields * f;
4906 size_t current_index;
4907 size_t size;
4908
4909 size = stat_info.st_size;
4910 current_index = 0;
4911 r = mailimf_fields_parse(mem, size, &amp;current_index, &amp;f);
4912 if (r == MAILIMF_NO_ERROR) {
4913 r = mailimf_crlf_parse(mem, size, &amp;current_index);
4914 /* ignore parse error of crlf */
4915
4916 r = mailimf_body_parse(mem, size, &amp;current_index, &amp;b);
4917 if (r == MAILIMF_NO_ERROR) {
4918
4919 display_body(b);
4920 /* do the things */
4921 status = EXIT_SUCCESS;
4922 mailimf_body_free(b);
4923 }
4924 mailimf_fields_free(f);
4925 }
4926 }
4927 munmap(mem, stat_info.st_size);
4928 }
4929
4930 close(fd);
4931 }
4932
4933 exit(status);
4934}
4935 </programlisting>
4936 </example>
4937
4938 </sect2>
4939
4940 <!-- mailimf_envelope_and_optional_fields_parse -->
4941 <sect2 id="mailimf-envelope-and-optional-fields-parse">
4942 <title>mailimf_envelope_and_optional_fields_parse</title>
4943
4944 <programlisting role="C">
4945#include &lt;libetpan/libetpan.h&gt;
4946
4947int
4948mailimf_envelope_and_optional_fields_parse(char * message, size_t length,
4949 size_t * index,
4950 struct mailimf_fields ** result);
4951 </programlisting>
4952
4953 <para>
4954 <command>mailimf_envelope_and_optional_fields_parse()</command>
4955 returns a list of most useful headers (parsed). The other
4956 headers will be placed in the list in a non-parsed form.
4957 </para>
4958
4959 <itemizedlist>
4960 <listitem>
4961 <para>
4962 <command>message</command> this is a string containing the header.
4963 </para>
4964 </listitem>
4965 <listitem>
4966 <para>
4967 <command>length</command> this is the size of the given string
4968 </para>
4969 </listitem>
4970 <listitem>
4971 <para>
4972 <command>index</command> index this is a pointer to the
4973 start of the header in the given string, <command>(*
4974 index)</command> is modified to point at the end
4975 of the parsed data
4976 </para>
4977 </listitem>
4978 <listitem>
4979 <para>
4980 <command>result</command> the result of the parse
4981 operation is stored in <command>(* result)</command>
4982 (see <xref linkend="mailimf-fields">).
4983 </para>
4984 </listitem>
4985 </itemizedlist>
4986
4987 <para>
4988 return <command>MAILIMF_NO_ERROR</command> on success,
4989 <command>MAILIMF_ERROR_XXX</command> on error.
4990 </para>
4991
4992 <example>
4993 <title>parsing commonly used fields and return other fields
4994 in a non-parsed form</title>
4995 <programlisting role="C">
4996#include &lt;libetpan/libetpan.h&gt;
4997#include &lt;sys/stat.h&gt;
4998#include &lt;sys/mman.h&gt;
4999
5000int main(int argc, char ** argv)
5001{
5002 int fd;
5003 int r;
5004
5005 status = EXIT_FAILURE;
5006
5007 fd = open("message.rfc2822", O_RDONLY);
5008 if (fd >= 0) {
5009 void * mem;
5010 struct stat stat_info;
5011
5012 r = fstat(fd, &amp;stat_info);
5013 if (r >= 0) {
5014 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
5015 if (mem != MAP_FAILED) {
5016 struct mailimf_fields * f;
5017 size_t current_index;
5018
5019 current_index = 0;
5020 r = mailimf_envelope_and_optional_fields_parse(mem, stat_info.st_size,
5021 &amp;current_index, &amp;f);
5022 if (r == MAILIMF_NO_ERROR) {
5023 display_fields(m);
5024 /* do the things */
5025 status = EXIT_SUCCESS;
5026 mailimf_fields_free(f);
5027 }
5028 }
5029 munmap(mem, stat_info.st_size);
5030 }
5031
5032 close(fd);
5033 }
5034
5035 exit(status);
5036}
5037 </programlisting>
5038 </example>
5039
5040 </sect2>
5041
5042 <!-- mailimf_envelope_fields_parse -->
5043 <sect2 id="mailimf-envelope-fields-parse">
5044 <title>mailimf_envelope_fields_parse</title>
5045
5046 <programlisting role="C">
5047#include &lt;libetpan/libetpan.h&gt;
5048
5049int mailimf_envelope_fields_parse(char * message, size_t length,
5050 size_t * index,
5051 struct mailimf_fields ** result);
5052 </programlisting>
5053
5054 <para>
5055 <command>mailimf_envelope_fields_parse()</command> return a
5056 list of most useful headers (parsed).
5057 </para>
5058
5059 <itemizedlist>
5060 <listitem>
5061 <para>
5062 <command>message</command> this is a string containing the header
5063 </para>
5064 </listitem>
5065 <listitem>
5066 <para>
5067 <command>length</command> this is the size of the given string
5068 </para>
5069 </listitem>
5070 <listitem>
5071 <para>
5072 <command>index</command> index this is a pointer to the
5073 start of the header in
5074 the given string, <command>(* index)</command> is
5075 modified to point at the end
5076 of the parsed data
5077 </para>
5078 </listitem>
5079 <listitem>
5080 <para>
5081 <command>result</command> the result of the parse
5082 operation is stored in
5083 <command>(* result)</command>
5084 (see <xref linkend="mailimf-fields">).
5085 </para>
5086 </listitem>
5087 </itemizedlist>
5088
5089 <para>
5090 return <command>MAILIMF_NO_ERROR</command> on success,
5091 <command>MAILIMF_ERROR_XXX</command> on error.
5092 </para>
5093
5094 <example>
5095 <title>parsing commonly used fields</title>
5096 <programlisting role="C">
5097#include &lt;libetpan/libetpan.h&gt;
5098#include &lt;sys/stat.h&gt;
5099#include &lt;sys/mman.h&gt;
5100
5101int main(int argc, char ** argv)
5102{
5103 int fd;
5104 int r;
5105
5106 status = EXIT_FAILURE;
5107
5108 fd = open("message.rfc2822", O_RDONLY);
5109 if (fd >= 0) {
5110 void * mem;
5111 struct stat stat_info;
5112
5113 r = fstat(fd, &amp;stat_info);
5114 if (r >= 0) {
5115 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
5116 if (mem != MAP_FAILED) {
5117 struct mailimf_fields * f;
5118 size_t current_index;
5119
5120 current_index = 0;
5121 r = mailimf_envelope_fields_parse(mem, stat_info.st_size,
5122 &amp;current_index, &amp;f);
5123 if (r == MAILIMF_NO_ERROR) {
5124 display_fields(m);
5125 /* do the things */
5126 status = EXIT_SUCCESS;
5127 mailimf_fields_free(f);
5128 }
5129 }
5130 munmap(mem, stat_info.st_size);
5131 }
5132
5133 close(fd);
5134 }
5135
5136 exit(status);
5137}
5138 </programlisting>
5139 </example>
5140
5141 </sect2>
5142
5143 <!-- mailimf_optional_fields_parse -->
5144 <sect2 id="mailimf-optional-fields-parse">
5145 <title>mailimf_optional_fields_parse</title>
5146
5147 <programlisting role="C">
5148#include &lt;libetpan/libetpan.h&gt;
5149
5150int
5151mailimf_envelope_and_optional_fields_parse(char * message, size_t length,
5152 size_t * index,
5153 struct mailimf_fields ** result);
5154 </programlisting>
5155
5156 <para>
5157 <command>mailimf_optional_fields_parse</command> return a
5158 list of non-parsed headers.
5159 </para>
5160
5161 <itemizedlist>
5162 <listitem>
5163 <para>
5164 <command>message</command> this is a string containing the header
5165 </para>
5166 </listitem>
5167 <listitem>
5168 <para>
5169 <command>length</command> this is the size of the given string
5170 </para>
5171 </listitem>
5172 <listitem>
5173 <para>
5174 <command>index</command> index this is a pointer to the
5175 start of the header in
5176 the given string, <command>(* index)</command> is
5177 modified to point at the end
5178 of the parsed data
5179 </para>
5180 </listitem>
5181 <listitem>
5182 <para>
5183 <command>result</command> the result of the parse
5184 operation is stored in
5185 <command>(* result)</command>
5186 (see <xref linkend="mailimf-fields">).
5187 </para>
5188 </listitem>
5189 </itemizedlist>
5190
5191 <para>
5192 return <command>MAILIMF_NO_ERROR</command> on success,
5193 <command>MAILIMF_ERROR_XXX</command> on error.
5194 </para>
5195
5196 <example>
5197 <title>parsing optional fields</title>
5198 <programlisting role="C">
5199#include &lt;libetpan/libetpan.h&gt;
5200#include &lt;sys/stat.h&gt;
5201#include &lt;sys/mman.h&gt;
5202
5203int main(int argc, char ** argv)
5204{
5205 int fd;
5206 int r;
5207
5208 status = EXIT_FAILURE;
5209
5210 fd = open("message.rfc2822", O_RDONLY);
5211 if (fd >= 0) {
5212 void * mem;
5213 struct stat stat_info;
5214
5215 r = fstat(fd, &amp;stat_info);
5216 if (r >= 0) {
5217 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
5218 if (mem != MAP_FAILED) {
5219 struct mailimf_fields * f;
5220 size_t current_index;
5221
5222 current_index = 0;
5223 r = mailimf_optional_fields_parse(mem, stat_info.st_size,
5224 &amp;current_index, &amp;f);
5225 if (r == MAILIMF_NO_ERROR) {
5226 display_fields(m);
5227 /* do the things */
5228 status = EXIT_SUCCESS;
5229 mailimf_fields_free(f);
5230 }
5231 }
5232 munmap(mem, stat_info.st_size);
5233 }
5234
5235 close(fd);
5236 }
5237
5238 exit(status);
5239}
5240 </programlisting>
5241 </example>
5242 </sect2>
5243
5244 <!-- mailimf_fields_parse -->
5245 <sect2 id="mailimf-fields-parse">
5246 <title>mailimf_fields_parse</title>
5247
5248 <programlisting role="C">
5249#include &lt;libetpan/libetpan.h&gt;
5250
5251int mailimf_fields_parse(char * message, size_t length,
5252 size_t * index,
5253 struct mailimf_fields ** result);
5254 </programlisting>
5255
5256 <para>
5257 <command>mailimf_fields_parse()</command> parse headers of a
5258 message.
5259 </para>
5260
5261 <itemizedlist>
5262 <listitem>
5263 <para>
5264 <command>message</command> this is a string containing the header
5265 </para>
5266 </listitem>
5267 <listitem>
5268 <para>
5269 <command>length</command> this is the size of the given string
5270 </para>
5271 </listitem>
5272 <listitem>
5273 <para>
5274 <command>index</command> index this is a pointer to the
5275 start of the header in
5276 the given string, <command>(* index)</command> is
5277 modified to point at the end
5278 of the parsed data
5279 </para>
5280 </listitem>
5281 <listitem>
5282 <para>
5283 <command>result</command> the result of the parse
5284 operation is stored in
5285 <command>(* result)</command>
5286 (see <xref linkend="mailimf-fields">).
5287 </para>
5288 </listitem>
5289 </itemizedlist>
5290
5291 <para>
5292 return <command>MAILIMF_NO_ERROR</command> on success,
5293 <command>MAILIMF_ERROR_XXX</command> on error.
5294 </para>
5295
5296 <example>
5297 <title>parsing header fields</title>
5298 <programlisting role="C">
5299#include &lt;libetpan/libetpan.h&gt;
5300#include &lt;sys/stat.h&gt;
5301#include &lt;sys/mman.h&gt;
5302
5303int main(int argc, char ** argv)
5304{
5305 int fd;
5306 int r;
5307
5308 status = EXIT_FAILURE;
5309
5310 fd = open("message.rfc2822", O_RDONLY);
5311 if (fd >= 0) {
5312 void * mem;
5313 struct stat stat_info;
5314
5315 r = fstat(fd, &amp;stat_info);
5316 if (r >= 0) {
5317 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
5318 if (mem != MAP_FAILED) {
5319 struct mailimf_fields * f;
5320 size_t current_index;
5321
5322 current_index = 0;
5323 r = mailimf_fields_parse(mem, stat_info.st_size,
5324 &amp;current_index, &amp;f);
5325 if (r == MAILIMF_NO_ERROR) {
5326 display_fields(f);
5327 /* do the things */
5328 status = EXIT_SUCCESS;
5329 mailimf_fields_free(f);
5330 }
5331 }
5332 munmap(mem, stat_info.st_size);
5333 }
5334
5335 close(fd);
5336 }
5337
5338 exit(status);
5339}
5340 </programlisting>
5341 </example>
5342 </sect2>
5343
5344 <!-- mailimf_ignore_field_parse -->
5345 <sect2 id="mailimf-ignore-field-parse">
5346 <title>mailimf_ignore_field_parse</title>
5347
5348 <programlisting role="C">
5349#include &lt;libetpan/libetpan.h&gt;
5350
5351int mailimf_ignore_field_parse(char * message, size_t length,
5352 size_t * index);
5353 </programlisting>
5354
5355 <para>
5356 <command>mailimf_ignore_field_parse()</command> skip the
5357 next header.
5358 </para>
5359
5360 <itemizedlist>
5361 <listitem>
5362 <para>
5363 <command>message</command> this is a string containing the header
5364 </para>
5365 </listitem>
5366 <listitem>
5367 <para>
5368 <command>length</command> this is the size of the given string
5369 </para>
5370 </listitem>
5371 <listitem>
5372 <para>
5373 <command>index</command> index this is a pointer to the
5374 start of the field to skip in
5375 the given string, <command>(* index)</command> is
5376 modified to point at the end
5377 of the parsed data
5378 </para>
5379 </listitem>
5380 </itemizedlist>
5381
5382 <para>
5383 return <command>MAILIMF_NO_ERROR</command> on success,
5384 <command>MAILIMF_ERROR_XXX</command> on error.
5385 </para>
5386
5387 <example>
5388 <title>skipping fields</title>
5389 <programlisting>
5390#include &lt;libetpan/libetpan.h&gt;
5391#include &lt;sys/stat.h&gt;
5392#include &lt;sys/mman.h&gt;
5393
5394int main(int argc, char ** argv)
5395{
5396 int fd;
5397 int r;
5398
5399 status = EXIT_FAILURE;
5400
5401 fd = open("message.rfc2822", O_RDONLY);
5402 if (fd >= 0) {
5403 void * mem;
5404 struct stat stat_info;
5405
5406 r = fstat(fd, &amp;stat_info);
5407 if (r >= 0) {
5408 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
5409 if (mem != MAP_FAILED) {
5410 size_t current_index;
5411
5412 current_index = 0;
5413 r = mailimf_ignore_field_parse(mem, stat_info.st_size,
5414 &amp;current_index);
5415 if (r == MAILIMF_NO_ERROR) {
5416 /* do the things */
5417 status = EXIT_SUCCESS;
5418 }
5419 }
5420 munmap(mem, stat_info.st_size);
5421 }
5422
5423 close(fd);
5424 }
5425
5426 exit(status);
5427}
5428 </programlisting>
5429 </example>
5430 </sect2>
5431
5432 <!-- mailimf_mailbox_list_parse -->
5433 <sect2 id="mailimf-mailbox-list-parse">
5434 <title>mailimf_mailbox_list_parse</title>
5435
5436 <programlisting role="C">
5437#include &lt;libetpan/libetpan.h&gt;
5438
5439int
5440mailimf_mailbox_list_parse(char * message, size_t length,
5441 size_t * index,
5442 struct mailimf_mailbox_list ** result);
5443 </programlisting>
5444
5445 <para>
5446 <command>mailimf_mailbox_list_parse()</command> parse a list
5447 of mailboxes in RFC 2822 form.
5448 </para>
5449
5450 <itemizedlist>
5451 <listitem>
5452 <para>
5453 <command>message</command> this is a string containing the
5454 list of mailboxes.
5455 </para>
5456 </listitem>
5457 <listitem>
5458 <para>
5459 <command>length</command> this is the size of the given
5460 string.
5461 </para>
5462 </listitem>
5463 <listitem>
5464 <para>
5465 <command>index</command> index this is a pointer to the
5466 start of the list of
5467 mailboxes in the given string,
5468 <command>(* index)</command> is modified to point
5469 at the end of the parsed data.
5470 </para>
5471 </listitem>
5472 <listitem>
5473 <para>
5474 <command>result</command> the result of the parse
5475 operation is stored in
5476 <command>(* result)</command>.
5477 (see <xref linkend="mailimf-mailbox-list">)
5478 </para>
5479 </listitem>
5480 </itemizedlist>
5481
5482 <para>
5483 return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on
5484 error.
5485 </para>
5486
5487 <example>
5488 <title>parsing a list of mailboxes</title>
5489 <programlisting>
5490#include &lt;libetpan/libetpan.h&gt;
5491#include &lt;sys/stat.h&gt;
5492#include &lt;sys/mman.h&gt;
5493
5494int main(int argc, char ** argv)
5495{
5496 int fd;
5497 int r;
5498
5499 status = EXIT_FAILURE;
5500
5501 fd = open("message.rfc2822", O_RDONLY);
5502 if (fd >= 0) {
5503 void * mem;
5504 struct stat stat_info;
5505
5506 r = fstat(fd, &amp;stat_info);
5507 if (r >= 0) {
5508 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
5509 if (mem != MAP_FAILED) {
5510 struct mailimf_mailbox_list * mb_list;
5511 size_t current_index;
5512
5513 current_index = 0;
5514 r = mailimf_mailbox_list_parse(mem, stat_info.st_size,
5515 &amp;current_index, &amp;mb_list);
5516 if (r == MAILIMF_NO_ERROR) {
5517 display_mailbox_list(mb_list);
5518 /* do the things */
5519 status = EXIT_SUCCESS;
5520 mailimf_mailbox_list_free(mb_list);
5521 }
5522 }
5523 munmap(mem, stat_info.st_size);
5524 }
5525
5526 close(fd);
5527 }
5528
5529 exit(status);
5530}
5531 </programlisting>
5532 </example>
5533
5534 </sect2>
5535
5536 <!-- mailimf_mailbox_parse -->
5537 <sect2 id="mailimf-mailbox-parse">
5538 <title>mailimf_mailbox_parse</title>
5539
5540 <programlisting role="C">
5541#include &lt;libetpan/libetpan.h&gt;
5542
5543int mailimf_mailbox_parse(char * message, size_t length,
5544 size_t * index,
5545 struct mailimf_mailbox ** result);
5546 </programlisting>
5547
5548 <para>
5549 <command>mailimf_mailbox_parse</command> parse a mailbox in
5550 RFC 2822 form.
5551 </para>
5552
5553 <itemizedlist>
5554 <listitem>
5555 <para>
5556 <command>message</command> this is a string containing the
5557 mailbox.
5558 </para>
5559 </listitem>
5560 <listitem>
5561 <para>
5562 <command>length</command> this is the size of the given
5563 string.
5564 </para>
5565 </listitem>
5566 <listitem>
5567 <para>
5568 <command>index</command> index this is a pointer to the
5569 start of the mailbox in the given string,
5570 <command>(* index)</command> is modified to point
5571 at the end of the parsed data.
5572 </para>
5573 </listitem>
5574 <listitem>
5575 <para>
5576 <command>result</command> the result of the parse
5577 operation is stored in
5578 <command>(* result)</command>.
5579 (see <xref linkend="mailimf-mailbox">)
5580 </para>
5581 </listitem>
5582 </itemizedlist>
5583
5584 <para>
5585 return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on
5586 error.
5587 </para>
5588
5589 <example>
5590 <title>parsing a mailbox</title>
5591 <programlisting role="C">
5592#include &lt;libetpan/libetpan.h&gt;
5593#include &lt;sys/stat.h&gt;
5594#include &lt;sys/mman.h&gt;
5595
5596int main(int argc, char ** argv)
5597{
5598 int fd;
5599 int r;
5600
5601 status = EXIT_FAILURE;
5602
5603 fd = open("message.rfc2822", O_RDONLY);
5604 if (fd >= 0) {
5605 void * mem;
5606 struct stat stat_info;
5607
5608 r = fstat(fd, &amp;stat_info);
5609 if (r >= 0) {
5610 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
5611 if (mem != MAP_FAILED) {
5612 struct mailimf_mailbox_list * mb_list;
5613 size_t current_index;
5614
5615 current_index = 0;
5616 r = mailimf_mailbox_parse(mem, stat_info.st_size,
5617 &amp;current_index, &amp;mb_list);
5618 if (r == MAILIMF_NO_ERROR) {
5619 display_mailbox_list(mb_list);
5620 /* do the things */
5621 status = EXIT_SUCCESS;
5622 mailimf_mailbox_free(mb_list);
5623 }
5624 }
5625 munmap(mem, stat_info.st_size);
5626 }
5627
5628 close(fd);
5629 }
5630
5631 exit(status);
5632}
5633 </programlisting>
5634 </example>
5635
5636 </sect2>
5637
5638 <!-- mailimf_message_parse -->
5639 <sect2 id="mailimf-message-parse">
5640 <title>mailimf_message_parse</title>
5641
5642 <programlisting>
5643#include &lt;libetpan/libetpan.h&gt;
5644
5645int mailimf_message_parse(char * message, size_t length,
5646 size_t * index,
5647 struct mailimf_message ** result);
5648 </programlisting>
5649
5650 <para>
5651 <command>mailimf_message_parse</command> parse message
5652 (headers and body).
5653 </para>
5654
5655 <itemizedlist>
5656 <listitem>
5657 <para>
5658 <command>message</command> this is a string containing
5659 the message content.
5660 </para>
5661 </listitem>
5662 <listitem>
5663 <para>
5664 <command>param</command> length this is the size of the given
5665 string.
5666 </para>
5667 </listitem>
5668 <listitem>
5669 <para>
5670 <command>param</command> index this is a pointer to the
5671 start of the message in
5672 the given string, <command>(* index)</command> is
5673 modified to point at the end
5674 of the parsed data.
5675 </para>
5676 </listitem>
5677 <listitem>
5678 <para>
5679 <command>param</command> result the result of the parse
5680 operation is stored in
5681 <command>(* result)</command>
5682 (see <xref linkend="mailimf-message">).
5683 </para>
5684 </listitem>
5685 </itemizedlist>
5686
5687 <example>
5688 <title>parsing a message</title>
5689 <programlisting role="C">
5690#include &lt;libetpan/libetpan.h&gt;
5691#include &lt;sys/stat.h&gt;
5692#include &lt;sys/mman.h&gt;
5693
5694int main(int argc, char ** argv)
5695{
5696 int fd;
5697 int r;
5698
5699 status = EXIT_FAILURE;
5700
5701 fd = open("message.rfc2822", O_RDONLY);
5702 if (fd >= 0) {
5703 void * mem;
5704 struct stat stat_info;
5705
5706 r = fstat(fd, &amp;stat_info);
5707 if (r >= 0) {
5708 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
5709 if (mem != MAP_FAILED) {
5710 struct mailimf_message * m;
5711 size_t current_index;
5712
5713 current_index = 0;
5714 r = mailimf_message_parse(mem, stat_info.st_size,
5715 &amp;current_index, &amp;m);
5716 if (r == MAILIMF_NO_ERROR) {
5717 display_message(m);
5718 /* do the things */
5719 status = EXIT_SUCCESS;
5720 mailimf_message_free(m);
5721 }
5722 }
5723 munmap(mem, stat_info.st_size);
5724 }
5725
5726 close(fd);
5727 }
5728
5729 exit(status);
5730}
5731 </programlisting>
5732 </example>
5733
5734 </sect2>
5735 </sect1>
5736
5737 <!-- helper functions -->
5738 <sect1>
5739 <title>Creation functions</title>
5740 <sect2 id="mailimf-mailbox-list-add">
5741 <title>mailimf_mailbox_list</title>
5742 <programlisting role="C">
5743#include &lt;libetpan/libetpan.h&gt;
5744
5745struct mailimf_mailbox_list *
5746mailimf_mailbox_list_new_empty();
5747
5748int mailimf_mailbox_list_add(struct mailimf_mailbox_list * mailbox_list,
5749 struct mailimf_mailbox * mb);
5750
5751int mailimf_mailbox_list_add_parse(struct mailimf_mailbox_list * mailbox_list,
5752 char * mb_str);
5753
5754int mailimf_mailbox_list_add_mb(struct mailimf_mailbox_list * mailbox_list,
5755 char * display_name, char * address);
5756 </programlisting>
5757
5758 <!-- mailimf_mailbox_list_new_empty -->
5759 <para>
5760 <command>mailimf_mailbox_list_new_empty()</command> creates a
5761 new empty list of mailboxes.
5762 </para>
5763
5764 <!-- mailimf_mailbox_list_add -->
5765 <para>
5766 <command>mailimf_mailbox_list_add</command> adds a mailbox
5767 to the list of mailboxes.
5768 </para>
5769
5770 <!-- mailimf_mailbox_list_add_parse -->
5771 <para>
5772 <command>mailimf_mailbox_list_add_parse</command> adds a
5773 mailbox given in form of a string to the list of mailboxes.
5774 </para>
5775
5776 <!-- mailimf_mailbox_list_add_mb -->
5777 <para>
5778 <command>mailimf_mailbox_list_add_mb</command> adds a
5779 mailbox given in form of a couple : display name, mailbox
5780 address.
5781 </para>
5782
5783 <itemizedlist>
5784 <listitem>
5785 <para>
5786 <command>mailbox_list</command> is the list of mailboxes.
5787 </para>
5788 </listitem>
5789 <listitem>
5790 <para>
5791 <command>mb</command> is a mailbox
5792 (see <xref linkend="mailimf-mailbox">).
5793 </para>
5794 </listitem>
5795 <listitem>
5796 <para>
5797 <command>mb_str</command> is a mailbox given in the form
5798 of a string.
5799 </para>
5800 </listitem>
5801 <listitem>
5802 <para>
5803 <command>display_name</command> is the display name.
5804 </para>
5805 </listitem>
5806 <listitem>
5807 <para>
5808 <command>address</command> is the mailbox address.
5809 </para>
5810 </listitem>
5811 </itemizedlist>
5812
5813 <example>
5814 <title>creating a list of mailboxes</title>
5815 <programlisting role="C">
5816#include &lt;libetpan/libetpan.h&gt;
5817
5818int main(int argc, char ** argv)
5819{
5820 struct mailimf_mailbox_list * mb_list;
5821 struct mailimf_mailbox * mb;
5822
5823 mb_list = mailimf_mailbox_list_new_empty();
5824
5825 mb = mailimf_mailbox_new(strdup("DINH Viet Hoa"),
5826 strdup("dinh.viet.hoa@free.fr"));
5827 mailimf_mailbox_list_add(mb_list, mb);
5828
5829 mailimf_mailbox_list_add_parse(mb_list, "foo bar &lt;foo@bar.org&gt;");
5830
5831 mailimf_mailbox_list_add_mb(mb_list, strdup("bar foo"), strdup("bar@foo.com"));
5832
5833 mailimf_mailbox_list_free(mb_list);
5834}
5835 </programlisting>
5836 </example>
5837
5838 </sect2>
5839 <sect2 id="mailimf-address-list-add">
5840 <title>mailimf_address_list</title>
5841 <programlisting role="C">
5842#include &lt;libetpan/libetpan.h&gt;
5843
5844struct mailimf_address_list * mailimf_address_list_new_empty();
5845
5846int mailimf_address_list_add(struct mailimf_address_list * address_list,
5847 struct mailimf_address * addr);
5848
5849int mailimf_address_list_add_parse(struct mailimf_address_list * address_list,
5850 char * addr_str);
5851
5852int mailimf_address_list_add_mb(struct mailimf_address_list * address_list,
5853 char * display_name, char * address);
5854 </programlisting>
5855
5856 <!-- mailimf_address_list_new_empty -->
5857 <para>
5858 <command>mailimf_address_list_new_empty()</command> creates a
5859 new empty list of addresses.
5860 </para>
5861
5862 <!-- mailimf_address_list_add -->
5863 <para>
5864 <command>mailimf_address_list_add</command> adds an address
5865 to the list of addresses.
5866 </para>
5867
5868 <!-- mailimf_address_list_add_parse -->
5869 <para>
5870 <command>mailimf_address_list_add_parse</command> adds an
5871 address given in form of a string to the list of addresses.
5872 </para>
5873
5874 <!-- mailimf_address_list_add_mb -->
5875 <para>
5876 <command>mailimf_address_list_add_mb</command> adds a
5877 mailbox given in form of a couple : display name, mailbox
5878 address.
5879 </para>
5880
5881 <itemizedlist>
5882 <listitem>
5883 <para>
5884 <command>address_list</command> is the list of mailboxes.
5885 </para>
5886 </listitem>
5887 <listitem>
5888 <para>
5889 <command>addr</command> is an address.
5890 (see <xref linkend="mailimf-address">).
5891 </para>
5892 </listitem>
5893 <listitem>
5894 <para>
5895 <command>addr_str</command> is an address given in the form of a
5896 string.
5897 </para>
5898 </listitem>
5899 <listitem>
5900 <para>
5901 <command>display_name</command> is the display name.
5902 </para>
5903 </listitem>
5904 <listitem>
5905 <para>
5906 <command>address</command> is the mailbox address.
5907 </para>
5908 </listitem>
5909 </itemizedlist>
5910
5911 </sect2>
5912 <sect2 id="mailimf-fields-add">
5913 <title>mailimf_fields</title>
5914 <programlisting role="C">
5915#include &lt;libetpan/libetpan.h&gt;
5916
5917struct mailimf_fields *
5918mailimf_fields_new_empty(void);
5919
5920struct mailimf_field * mailimf_field_new_custom(char * name, char * value);
5921
5922int mailimf_fields_add(struct mailimf_fields * fields,
5923 struct mailimf_field * field);
5924
5925int mailimf_fields_add_data(struct mailimf_fields * fields,
5926 struct mailimf_date_time * date,
5927 struct mailimf_mailbox_list * from,
5928 struct mailimf_mailbox * sender,
5929 struct mailimf_address_list * reply_to,
5930 struct mailimf_address_list * to,
5931 struct mailimf_address_list * cc,
5932 struct mailimf_address_list * bcc,
5933 char * msg_id,
5934 clist * in_reply_to,
5935 clist * references,
5936 char * subject);
5937
5938struct mailimf_fields *
5939mailimf_fields_new_with_data_all(struct mailimf_date_time * date,
5940 struct mailimf_mailbox_list * from,
5941 struct mailimf_mailbox * sender,
5942 struct mailimf_address_list * reply_to,
5943 struct mailimf_address_list * to,
5944 struct mailimf_address_list * cc,
5945 struct mailimf_address_list * bcc,
5946 char * message_id,
5947 clist * in_reply_to,
5948 clist * references,
5949 char * subject);
5950
5951struct mailimf_fields *
5952mailimf_fields_new_with_data(struct mailimf_mailbox_list * from,
5953 struct mailimf_mailbox * sender,
5954 struct mailimf_address_list * reply_to,
5955 struct mailimf_address_list * to,
5956 struct mailimf_address_list * cc,
5957 struct mailimf_address_list * bcc,
5958 clist * in_reply_to,
5959 clist * references,
5960 char * subject);
5961
5962char * mailimf_get_message_id(void);
5963
5964struct mailimf_date_time * mailimf_get_current_date(void);
5965
5966int
5967mailimf_resent_fields_add_data(struct mailimf_fields * fields,
5968 struct mailimf_date_time * resent_date,
5969 struct mailimf_mailbox_list * resent_from,
5970 struct mailimf_mailbox * resent_sender,
5971 struct mailimf_address_list * resent_to,
5972 struct mailimf_address_list * resent_cc,
5973 struct mailimf_address_list * resent_bcc,
5974 char * resent_msg_id);
5975
5976struct mailimf_fields *
5977mailimf_resent_fields_new_with_data_all(struct mailimf_date_time *
5978 resent_date, struct mailimf_mailbox_list * resent_from,
5979 struct mailimf_mailbox * resent_sender,
5980 struct mailimf_address_list * resent_to,
5981 struct mailimf_address_list * resent_cc,
5982 struct mailimf_address_list * resent_bcc,
5983 char * resent_msg_id);
5984
5985struct mailimf_fields *
5986mailimf_resent_fields_new_with_data(struct mailimf_mailbox_list * from,
5987 struct mailimf_mailbox * resent_sender,
5988 struct mailimf_address_list * resent_to,
5989 struct mailimf_address_list * resent_cc,
5990 struct mailimf_address_list * resent_bcc);
5991 </programlisting>
5992
5993 <itemizedlist>
5994 <listitem>
5995 <para>
5996 <command>from</command> is the parsed content of the
5997 From field
5998 (see <xref linkend="mailimf-from">).
5999 </para>
6000 </listitem>
6001 <listitem>
6002 <para>
6003 <command>sender</command> is the parsed content of the
6004 Sender field
6005 (see <xref linkend="mailimf-sender">).
6006 </para>
6007 </listitem>
6008 <listitem>
6009 <para>
6010 <command>reply_to</command> is the parsed content of the
6011 <command>Reply-To</command> field
6012 (see <xref linkend="mailimf-reply-to">).
6013 </para>
6014 </listitem>
6015 <listitem>
6016 <para>
6017 <command>to</command> is the parsed content of the
6018 <command>To</command> field
6019 (see <xref linkend="mailimf-to">).
6020 </para>
6021 </listitem>
6022 <listitem>
6023 <para>
6024 <command>cc</command> is the parsed content of the
6025 <command>Cc</command> field
6026 (see <xref linkend="mailimf-cc">).
6027 </para>
6028 </listitem>
6029 <listitem>
6030 <para>
6031 <command>bcc</command> is the parsed content of the
6032 <command>Bcc</command> field
6033 (see <xref linkend="mailimf-bcc">).
6034 </para>
6035 </listitem>
6036 <listitem>
6037 <para>
6038 <command>message_id</command> is the parsed content of
6039 the <command>Message-ID</command> field
6040 (see <xref linkend="mailimf-message-id">).
6041 </para>
6042 </listitem>
6043 <listitem>
6044 <para>
6045 <command>in_reply_to</command> is the parsed content of
6046 the <command>In-Reply-To</command> field
6047 (see <xref linkend="mailimf-in-reply-to">).
6048 </para>
6049 </listitem>
6050 <listitem>
6051 <para>
6052 <command>references</command> is the parsed content of
6053 the <command>References</command> field
6054 (see <xref linkend="mailimf-references">).
6055 </para>
6056 </listitem>
6057 <listitem>
6058 <para>
6059 <command>subject</command> is the content of the
6060 <command>Subject</command> field
6061 (see <xref linkend="mailimf-subject">).
6062 </para>
6063 </listitem>
6064 <listitem>
6065 <para>
6066 <command>resent_date</command> is the parsed content of
6067 the <command>Resent-Date</command> field
6068 (see <xref linkend="mailimf-orig-date">).
6069 </para>
6070 </listitem>
6071 <listitem>
6072 <para>
6073 <command>resent_from</command> is the parsed content of
6074 the <command>Resent-From</command> field
6075 (see <xref linkend="mailimf-from">).
6076 </para>
6077 </listitem>
6078 <listitem>
6079 <para>
6080 <command>resent_sender</command> is the parsed content of the
6081 <command>Resent-Sender</command> field
6082 (see <xref linkend="mailimf-sender">).
6083 </para>
6084 </listitem>
6085 <listitem>
6086 <para>
6087 <command>resent_to</command> is the parsed content of
6088 the <command>Resent-To</command> field
6089 (see <xref linkend="mailimf-to">).
6090 </para>
6091 </listitem>
6092 <listitem>
6093 <para>
6094 <command>resent_cc</command> is the parsed content of
6095 the <command>Resent-Cc</command> field
6096 (see <xref linkend="mailimf-cc">).
6097 </para>
6098 </listitem>
6099 <listitem>
6100 <para>
6101 <command>resent_bcc</command> is the parsed content of the
6102 <command>Resent-Bcc</command> field
6103 (see <xref linkend="mailimf-bcc">).
6104 </para>
6105 </listitem>
6106 <listitem>
6107 <para>
6108 <command>resent_msg_id</command> is the parsed content of the
6109 <command>Resent-Message-ID</command> field
6110 (see <xref linkend="mailimf-message-id">).
6111 </para>
6112 </listitem>
6113 </itemizedlist>
6114
6115 <!-- mailimf_fields_new_empty -->
6116 <para>
6117 <command>mailimf_fields_new_empty()</command> creates a new
6118 empty set of headers.
6119 </para>
6120
6121 <!-- mailimf_fields_new_custom -->
6122 <para>
6123 <command>mailimf_field_new_custom()</command> creates a new
6124 custom header.
6125 </para>
6126
6127 <!-- mailimf_fields_add -->
6128 <para>
6129 <command>mailimf_fields_add()</command> adds a header to the
6130 set of headers.
6131 </para>
6132
6133 <!-- mailimf_fields_add_data -->
6134 <para>
6135 <command>mailimf_fields_add_data()</command> adds some headers
6136 to the set of headers.
6137 </para>
6138
6139 <!-- mailimf_fields_new_with_data_all -->
6140 <para>
6141 <command>mailimf_fields_new_with_data_all()</command> creates
6142 a set of headers with some headers (including Date and
6143 Message-ID).
6144 </para>
6145
6146 <!-- mailimf_fields_new_with_data -->
6147 <para>
6148 <command>mailimf_fields_new_with_data()</command> creates a
6149 set of headers with some headers (Date and Message-ID will
6150 be generated).
6151 </para>
6152
6153 <!-- mailimf_get_message_id -->
6154 <para>
6155 <command>mailimf_get_message_id()</command> generates a
6156 Message-ID. The result must be freed using
6157 <command>free()</command>.
6158 </para>
6159
6160 <!-- mailimf_get_current_date -->
6161 <para>
6162 <command>mailimf_get_current_date()</command> generates a
6163 Date. The result must be freed using
6164 <command>mailimf_date_time_free</command>.
6165 </para>
6166
6167 <!-- mailimf_resent_fields_add_data -->
6168 <para>
6169 <command>mailimf_resent_fields_add_data()</command> adds some
6170 resent headers to the set of headers.
6171 </para>
6172
6173 <!-- mailimf_resent_fields_new_with_data_all -->
6174 <para>
6175 <command>mailimf_resent_fields_new_with_data_all()</command>
6176 creates a set of headers with some resent headers (including
6177 Resent-Date and Resent-Message-ID).
6178 </para>
6179
6180 <!-- mailimf_resent_fields_new_with_data -->
6181 <para>
6182 <command>mailimf_resent_fields_new_with_data()</command>
6183 creates a set of headers with some resent headers
6184 (Resent-Date and Resent-Message-ID will be generated)
6185 </para>
6186
6187 <example>
6188 <title>creation of header fields</title>
6189 <programlisting role="C">
6190#include &lt;libetpan/libetpan.h&gt;
6191
6192int main(int argc, char ** argv)
6193{
6194 struct mailimf_fields * fields;
6195 struct mailimf_field * field;
6196 struct mailimf_date_time * date;
6197 char * msg_id;
6198 struct mailimf_mailbox_list * from;
6199 struct mailimf_address_list * to;
6200
6201 fields = mailimf_fields_new_empty();
6202 field = mailimf_field_new_custom(strdup("X-Mailer"), strdup("my-mailer"));
6203 mailimf_fields_add(fields, field);
6204
6205 from = mailimf_mailbox_list_new_empty();
6206 mailimf_mailbox_list_add_mb(from, strdup("DINH Viet Hoa"), strdup("dinh.viet.hoa@free.fr");
6207 date = mailimf_get_current_date();
6208 msg_id = mailimf_get_message_id();
6209 to = mailimf_address_list_new_empty();
6210 mailimf_address_list_add_mb(to, strdup("FOO Bar"), strdup("foo@bar.org");
6211
6212 mailimf_fields_add_data(fields, date, from, NULL, NULL, to, NULL, NULL,
6213 msg_id, NULL, NULL, strdup("hello"));
6214
6215 /* do the things */
6216
6217 mailimf_fields_free(fields);
6218}
6219
6220#include &lt;libetpan/libetpan.h&gt;
6221
6222int main(int argc, char ** argv)
6223{
6224 struct mailimf_fields * fields;
6225 struct mailimf_mailbox_list * from;
6226 struct mailimf_address_list * to;
6227 struct mailimf_date_time * date;
6228 char * msg_id;
6229
6230 from = mailimf_mailbox_list_new_empty();
6231 mailimf_mailbox_list_add_mb(from, strdup("DINH Viet Hoa"), strdup("dinh.viet.hoa@free.fr");
6232 to = mailimf_address_list_new_empty();
6233 mailimf_address_list_add_mb(to, strdup("FOO Bar"), strdup("foo@bar.org");
6234 date = mailimf_get_current_date();
6235 msg_id = mailimf_get_message_id();
6236
6237 fields = mailimf_fields_new_with_all_data(date, from, NULL, NULL, to, NULL, NULL,
6238 msg_id, NULL, NULL, strdup("hello"));
6239
6240 /* do the things */
6241
6242 mailimf_fields_free(fields);
6243}
6244
6245#include &lt;libetpan/libetpan.h&gt;
6246
6247int main(int argc, char ** argv)
6248{
6249 struct mailimf_fields * fields;
6250 struct mailimf_mailbox_list * from;
6251 struct mailimf_address_list * to;
6252
6253 from = mailimf_mailbox_list_new_empty();
6254 mailimf_mailbox_list_add_mb(from, strdup("DINH Viet Hoa"), strdup("dinh.viet.hoa@free.fr");
6255 to = mailimf_address_list_new_empty();
6256 mailimf_address_list_add_mb(to, strdup("FOO Bar"), strdup("foo@bar.org");
6257
6258 fields = mailimf_fields_new_with_data(from, NULL, NULL, to, NULL, NULL,
6259 NULL, NULL, strdup("hello"));
6260
6261 /* do the things */
6262
6263 mailimf_fields_free(fields);
6264}
6265 </programlisting>
6266 </example>
6267 </sect2>
6268 </sect1>
6269
6270 <!-- rendering functions -->
6271 <sect1>
6272 <title>Rendering of messages</title>
6273 <sect2 id="mailimf-fields-write">
6274 <title>Header fields</title>
6275 <programlisting>
6276#include &lt;libetpan/libetpan.h&gt;
6277
6278int mailimf_fields_write(FILE * f, int * col,
6279 struct mailimf_fields * fields);
6280
6281int mailimf_envelope_fields_write(FILE * f, int * col,
6282 struct mailimf_fields * fields);
6283
6284int mailimf_field_write(FILE * f, int * col,
6285 struct mailimf_field * field);
6286 </programlisting>
6287
6288 <itemizedlist>
6289 <listitem>
6290 <para>
6291 <command>col</command> current column is given for wrapping
6292 purpose in <command>(* col)</command>,
6293 the resulting columns will be returned..
6294 </para>
6295 </listitem>
6296 <listitem>
6297 <para>
6298 <command>f</command> is the file descriptor. It can be
6299 stdout for example.
6300 </para>
6301 </listitem>
6302 <listitem>
6303 <para>
6304 <command>fields</command> is the header fields
6305 (see <xref linkend="mailimf-fields">).
6306 </para>
6307 </listitem>
6308 <listitem>
6309 <para>
6310 <command>field</command> is a field
6311 (see <xref linkend="mailimf-field">).
6312 </para>
6313 </listitem>
6314 </itemizedlist>
6315
6316 <!-- mailimf_fields_write -->
6317 <para>
6318 <command>mailimf_fields_write</command> outputs the set of
6319 header fields.
6320 </para>
6321
6322 <!-- mailimf_envelope_fields_write -->
6323 <para>
6324 <command>mailimf_envelope_fields_write</command> outputs the
6325 set of header fields except the optional fields.
6326 </para>
6327
6328 <!-- mailimf_field_write -->
6329 <para>
6330 <command>mailimf_field_write</command> outputs a header.
6331 </para>
6332
6333 <example>
6334 <title>rendering of fields</title>
6335 <programlisting role="C">
6336int main(int argc, char ** argv)
6337{
6338 struct mailimf_fields * fields;
6339 int col;
6340
6341 /* look at the example in mailimf_fields to see how to
6342 build a mailimf_fields */
6343 fields = build_imf_fields();
6344
6345 col = 0;
6346 mailimf_fields_write(stdout, &amp;col, fields);
6347
6348 mailimf_fields_free(fields);
6349}
6350
6351int main(int argc, char ** argv)
6352{
6353 struct mailimf_fields * fields;
6354 int col;
6355
6356 /* look at the example in mailimf_fields to see how to
6357 build a mailimf_fields */
6358 fields = build_imf_fields();
6359
6360 col = 0;
6361 mailimf_envelope_fields_write(stdout, &amp;col, fields);
6362
6363 mailimf_fields_free(fields);
6364}
6365
6366int main(int argc, char ** argv)
6367{
6368 struct mailimf_field * field;
6369 int col;
6370
6371 field = mailimf_field_new_custom(strdup("X-Mailer"), strdup("my mailer"));
6372
6373 col = 0;
6374 mailimf_field_write(stdout, &amp;col, field);
6375
6376 mailimf_field_free(field);
6377}
6378 </programlisting>
6379 </example>
6380 </sect2>
6381 </sect1>
6382 </chapter>
6383
6384
6385 <!-- MIME -->
6386 <chapter>
6387 <title>MIME</title>
6388
6389 <para>
6390 libEtPan! implements a MIME message parser (also known as
6391 messages with attachments or
6392 multipart messages). This also allows to generate MIME messages.
6393 </para>
6394
6395 <warning>
6396 <para>
6397 All allocation functions will take as argument allocated data
6398 and will store these data in the structure they will allocate.
6399 Data should be persistant during all the use of the structure
6400 and will be freed by the free function of the structure
6401 </para>
6402
6403 <para>
6404 allocation functions will return <command>NULL</command> on failure
6405
6406 functions returning integer will be returning one of the
6407 following error code:
6408 <command>MAILIMF_NO_ERROR</command>,
6409 <command>MAILIMF_ERROR_PARSE</command>,
6410 <command>MAILIMF_ERROR_MEMORY</command>,
6411 <command>MAILIMF_ERROR_INVAL</command>,
6412 or <command>MAILIMF_ERROR_FILE</command>.
6413 </para>
6414 </warning>
6415
6416 <sect1>
6417 <title>Quick start</title>
6418
6419 <para>
6420 You will need this module when you want to parse a MIME
6421 message.
6422 </para>
6423
6424 <sect2>
6425 <title>Parse MIME message</title>
6426 <para>
6427 You will use the following function :
6428 </para>
6429 <itemizedlist>
6430 <listitem>
6431 <para>
6432 <command>mailmime_parse</command>
6433 (<xref linkend="mailimf-envelope-and-optional-fields-parse">)
6434 </para>
6435 </listitem>
6436 </itemizedlist>
6437 </sect2>
6438
6439 <sect2>
6440 <title>Render the MIME message</title>
6441 <para>
6442 Build your MIME message, then use
6443 <command>mailmime_write</command>
6444 (<xref linkend="mailmime-write">)
6445 to render a MIME message.
6446 </sect2>
6447 </sect1>
6448
6449 <!-- Data types-->
6450 <sect1>
6451 <title>Data types</title>
6452 <!-- mailmime_composite_type -->
6453 <sect2 id="mailmime-composite-type">
6454 <title>mailmime_composite_type - Composite MIME type</title>
6455
6456 <programlisting role="C">
6457#include &lt;libetpan/libetpan.h&gt;
6458
6459enum {
6460 MAILMIME_COMPOSITE_TYPE_ERROR,
6461 MAILMIME_COMPOSITE_TYPE_MESSAGE,
6462 MAILMIME_COMPOSITE_TYPE_MULTIPART,
6463 MAILMIME_COMPOSITE_TYPE_EXTENSION
6464};
6465
6466struct mailmime_composite_type {
6467 int ct_type;
6468 char * ct_token;
6469};
6470
6471struct mailmime_composite_type *
6472mailmime_composite_type_new(int ct_type, char * ct_token);
6473
6474void mailmime_composite_type_free(struct mailmime_composite_type * ct);
6475 </programlisting>
6476
6477 <para>
6478 This is a MIME composite type such as <command>message</command> or
6479 <command>multipart</command>.
6480 </para>
6481
6482 <para>
6483 <command>ct_type</command> can have one of the 3 following values :
6484 <command>MAILMIME_COMPOSITE_TYPE_MESSAGE</command> when the
6485 composite MIME type
6486 is <command>message</command>,
6487 <command>MAILMIME_COMPOSITE_TYPE_MULTIPART</command> when
6488 the composite MIME type
6489 is <command> multipart</command>,
6490 <command>MAILMIME_COMPOSITE_TYPE_EXTENSION</command> for
6491 other and <command>ct_token</command> is set
6492 in this case.
6493 <command>MAILMIME_COMPOSITE_TYPE_ERROR</command> is used
6494 internally on parse error.
6495 </para>
6496
6497 <para>
6498 <command>mailmime_composite_type_new()</command> creates and
6499 initializes
6500 a data structure with a value.
6501 Structures given as argument are referenced by the created
6502 object and will be freed if the object is released.
6503 </para>
6504
6505 <para>
6506 <command>mailmime_composite_type_free()</command> frees
6507 memory used by
6508 the structure and substructures will also be released.
6509 </para>
6510
6511 <example>
6512 <title>create and display MIME composite type</title>
6513 <programlisting role="C">
6514#include &lt;libetpan/libetpan.h&gt;
6515
6516int main(void)
6517{
6518 struct mailmime_composite_type * ct;
6519
6520 ct = mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MULTIPART, NULL);
6521
6522 /* do your things ... */
6523
6524 mailmime_composite_type_free(ct);
6525
6526 exit(EXIT_SUCCESS);
6527}
6528
6529void display_composite_type()
6530{
6531 switch (ct-&gt;type) {
6532 case MAILMIME_COMPOSITE_TYPE_MESSAGE:
6533 printf("composite type is message\n");
6534 break;
6535 case MAILMIME_COMPOSITE_TYPE_MULTIPART:
6536 printf("composite type is multipart\n");
6537 break;
6538 case MAILMIME_COMPOSITE_TYPE_EXTENSION:
6539 printf("composite type: %s\n", ct-&gt;ct_token);
6540 break;
6541 }
6542}
6543 </programlisting>
6544 </example>
6545
6546 </sect2>
6547
6548 <!-- mailmime_content -->
6549 <sect2 id="mailmime-content">
6550 <title>mailmime_content - MIME content type (Content-Type)</title>
6551
6552 <programlisting role="C">
6553#include &lt;libetpan/libetpan.h&gt;
6554
6555struct mailmime_content {
6556 struct mailmime_type * ct_type;
6557 char * ct_subtype;
6558 clist * ct_parameters; /* elements are (struct mailmime_parameter *) */
6559};
6560
6561struct mailmime_content *
6562mailmime_content_new(struct mailmime_type * ct_type,
6563 char * ct_subtype,
6564 clist * ct_parameters);
6565
6566void mailmime_content_free(struct mailmime_content * content);
6567 </programlisting>
6568
6569 <para>
6570 This is a MIME content type such as <command>message/rfc822</command> or
6571 <command>text/plain</command>.
6572 </para>
6573
6574 <itemizedlist>
6575 <listitem>
6576 <para>
6577 <command>ct_type</command> is the main MIME type,
6578 for example <command>text</command> in
6579 <command>plain/text</command>
6580 (see <xref linkend="mailmime-type">).
6581 </para>
6582 <para>
6583 <command>ct_subtype</command> is the MIME subtype,
6584 for example <command>plain</command> in
6585 <command>plain/text</command>.
6586 </para>
6587 </listitem>
6588 <listitem>
6589 <para>
6590 <command>ct_parameters</command> is the list of parameters for
6591 the given MIME type. For example, for <command>plain/text</command>,
6592 we can find <command>charset=iso-8859-1</command>,
6593 <command>format=flowed</command>. Each element of the list
6594 if of type <command>struct mailmime_parameter *</command>
6595 (see <xref linkend="mailmime-parameter">).
6596 </para>
6597 </listitem>
6598 </itemizedlist>
6599
6600 <para>
6601 <command>mailmime_content_new()</command> creates and initializes
6602 a data structure with a value.
6603 Structures given as argument are referenced by the created
6604 object and will be freed if the object is released.
6605 </para>
6606
6607 <para>
6608 <command>mailmime_content_free()</command> frees memory used by
6609 the structure and substructures will also be released.
6610 </para>
6611
6612 <example>
6613 <title>Creation and display of MIME content type</title>
6614 <programlisting role="C">
6615#include &lt;libetpan/libetpan.h&gt;
6616
6617int main(void)
6618{
6619 struct mailmime_content * content;
6620 struct mailmime_type * type;
6621 struct mailmime_discrete_type * dt;
6622 struct mailmime_parameter * param;
6623 clist * param_list;
6624
6625 dt = mailmime_discrete_type_new(MAILMIME_DISCRETE_TYPE_TEXT, NULL);
6626 type = mailmime_type_new(MAILMIME_TYPE_DISCRETE_TYPE, dt, NUL);
6627 param_list = clist_new();
6628 param = mailmime_parameter_new(strdup("charset"), strdup("iso-8859-1"));
6629 clist_append(param_list, param);
6630
6631 content = mailmime_content_new(type, strdup("plain"), param_list);
6632
6633 /* do your things */
6634
6635 exit(EXIT_SUCCESS);
6636}
6637
6638void display_mime_content(struct mailmime_content * content_type)
6639{
6640 clistiter * cur;
6641
6642 printf("type:\n");
6643 display_type(content_type-&gt;ct_type);
6644 printf("\n");
6645 printf("subtype: %s\n", content_type-&gt;ct_subtype);
6646 printf("\n");
6647
6648 for(cur = clist_begin(content_type-&gt;ct_parameters) ; cur != NULL ;
6649 cur = clist_next(cur)) {
6650 struct mailmime_parameter * param;
6651
6652 param = clist_content(cur);
6653 display_mime_parameter(param);
6654 printf("\n");
6655 }
6656 printf("\n");
6657}
6658 </programlisting>
6659 </example>
6660
6661 </sect2>
6662
6663 <!-- mailmime_discrete_type -->
6664 <sect2 id="mailmime-discrete-type">
6665 <title>mailmime_discrete_type - MIME discrete type</title>
6666
6667 <programlisting role="C">
6668#include &lt;libetpan/libetpan.h&gt;
6669
6670enum {
6671 MAILMIME_DISCRETE_TYPE_ERROR,
6672 MAILMIME_DISCRETE_TYPE_TEXT,
6673 MAILMIME_DISCRETE_TYPE_IMAGE,
6674 MAILMIME_DISCRETE_TYPE_AUDIO,
6675 MAILMIME_DISCRETE_TYPE_VIDEO,
6676 MAILMIME_DISCRETE_TYPE_APPLICATION,
6677 MAILMIME_DISCRETE_TYPE_EXTENSION
6678};
6679
6680struct mailmime_discrete_type {
6681 int dt_type;
6682 char * dt_extension;
6683};
6684
6685struct mailmime_discrete_type *
6686mailmime_discrete_type_new(int dt_type, char * dt_extension);
6687
6688void mailmime_discrete_type_free(struct mailmime_discrete_type *
6689 discrete_type);
6690 </programlisting>
6691
6692 <para>
6693 This is a MIME discrete type such as <command>text</command> or
6694 <command>image</command>. This is also known as single part. This kind
6695 of part does not have any child.
6696 </para>
6697
6698 <para>
6699 <command>dt_type</command> is one of the given values :
6700 <command>MAILMIME_DISCRETE_TYPE_TEXT</command> if part is text,
6701 <command>MAILMIME_DISCRETE_TYPE_IMAGE</command> if part is an image,
6702 <command>MAILMIME_DISCRETE_TYPE_AUDIO</command> if part is
6703 audio data,
6704 <command>MAILMIME_DISCRETE_TYPE_VIDEO</command> if part is video,
6705 <command>MAILMIME_DISCRETE_TYPE_APPLICATION</command> if
6706 part is application data or
6707 <command>MAILMIME_DISCRETE_TYPE_EXTENSION</command> for other.
6708 In the case of <command>MAILMIME_DISCRETE_TYPE_EXTENSION</command>,
6709 <command>dt_extension</command> is filled in.
6710 <command>MAILMIME_DISCRETE_TYPE_ERROR</command> is used internally.
6711 </para>
6712
6713 <para>
6714 <command>mailmime_discrete_type_new()</command> creates and
6715 initializes
6716 a data structure with a value.
6717 Structures given as argument are referenced by the created
6718 object and will be freed if the object is released.
6719 </para>
6720
6721 <para>
6722 <command>mailmime_discrete_type_free()</command> frees
6723 memory used by
6724 the structure and substructures will also be released.
6725 </para>
6726
6727 <example>
6728 <title>Creation and display of MIME discrete type</title>
6729 <programlisting role="C">
6730#include &lt;libetpan/libetpan.h&gt;
6731
6732/* standard type */
6733
6734int main(int argc, char ** argv)
6735{
6736 struct mailmime_discrete_type * discrete_type;
6737
6738 discrete_type = mailmime_discrete_type_new(MAILMIME_DISCRETE_TYPE_TEXT,
6739 NULL);
6740
6741 /* do the things */
6742
6743 mailmime_discrete_type_free(discrete_type);
6744}
6745
6746/* extension */
6747
6748int main(int argc, char ** argv)
6749{
6750 struct mailmime_discrete_type * discrete_type;
6751
6752 discrete_type = mailmime_discrete_type_new(MAILMIME_DISCRETE_TYPE_EXTENSION,
6753 strdup("my-type"));
6754
6755 /* do the things */
6756
6757 mailmime_discrete_type_free(discrete_type);
6758}
6759
6760void display_mime_discrete_type(struct mailmime_discrete_type * discrete_type)
6761{
6762 switch (discrete_type-&gt;dt_type) {
6763 case MAILMIME_DISCRETE_TYPE_TEXT:
6764 printf("text\n");
6765 break;
6766 case MAILMIME_DISCRETE_TYPE_IMAGE:
6767 printf("image\n");
6768 break;
6769 case MAILMIME_DISCRETE_TYPE_AUDIO:
6770 printf("audio\n");
6771 break;
6772 case MAILMIME_DISCRETE_TYPE_VIDEO:
6773 printf("video\n");
6774 break;
6775 case MAILMIME_DISCRETE_TYPE_APPLICATION:
6776 printf("application\n");
6777 break;
6778 case MAILMIME_DISCRETE_TYPE_EXTENSION:
6779 printf("extension : %s\n", discrete_type-&gt;dt_extension);
6780 break;
6781 }
6782}
6783 </programlisting>
6784 </example>
6785
6786 </sect2>
6787
6788 <!-- mailmime_field -->
6789 <sect2 id="mailmime-field">
6790 <title>mailmime_field - MIME header field</title>
6791
6792 <programlisting role="C">
6793#include &lt;libetpan/libetpan.h&gt;
6794
6795enum {
6796 MAILMIME_FIELD_NONE,
6797 MAILMIME_FIELD_TYPE,
6798 MAILMIME_FIELD_TRANSFER_ENCODING,
6799 MAILMIME_FIELD_ID,
6800 MAILMIME_FIELD_DESCRIPTION,
6801 MAILMIME_FIELD_VERSION,
6802 MAILMIME_FIELD_DISPOSITION,
6803 MAILMIME_FIELD_LANGUAGE,
6804};
6805
6806struct mailmime_field {
6807 int fld_type;
6808 union {
6809 struct mailmime_content * fld_content;
6810 struct mailmime_mechanism * fld_encoding;
6811 char * fld_id;
6812 char * fld_description;
6813 uint32_t fld_version;
6814 struct mailmime_disposition * fld_disposition;
6815 struct mailmime_language * fld_language;
6816 } fld_data;
6817};
6818
6819struct mailmime_field *
6820mailmime_field_new(int fld_type,
6821 struct mailmime_content * fld_content,
6822 struct mailmime_mechanism * fld_encoding,
6823 char * fld_id,
6824 char * fld_description,
6825 uint32_t fld_version,
6826 struct mailmime_disposition * fld_disposition,
6827 struct mailmime_language * fld_language);
6828
6829void mailmime_field_free(struct mailmime_field * field);
6830 </programlisting>
6831
6832 <para>
6833 This is a parsed MIME header field;
6834 </para>
6835
6836 <itemizedlist>
6837 <listitem>
6838 <para>
6839 <command>fld_type</command> is the type of MIME header field. The value can
6840 be
6841 <command>MAILMIME_FIELD_TYPE</command>
6842 if field is <command>Content-Type</command>,
6843 <command>MAILMIME_FIELD_TRANSFER_ENCODING</command>
6844 if field is <command>Content-Transfer-Encoding</command>,
6845 <command>MAILMIME_FIELD_ID</command>
6846 if field is <command>Content-ID</command>,
6847 <command>MAILMIME_FIELD_DESCRIPTION</command>
6848 if field is <command>Content-Description</command>,
6849 <command>MAILMIME_FIELD_VERSION</command>
6850 if field is <command>MIME-Version</command>,
6851 <command>MAILMIME_FIELD_DISPOSITION</command>
6852 if field is <command>Content-Disposition</command> or
6853 <command>MAILMIME_FIELD_LANGUAGE</command>
6854 if field is <command>Content-Language</command>.
6855 <command>MAILMIME_FIELD_NONE</command> is used internally.
6856 </para>
6857 </listitem>
6858 <listitem>
6859 <para>
6860 <command>fld_data.fld_content</command> is set in case of
6861 <command>Content-Type</command>.
6862 (see <xref linkend="mailmime-content">).
6863 </para>
6864 </listitem>
6865 <listitem>
6866 <para>
6867 <command>fld_data.fld_encoding</command> is set in case of
6868 <command>Content-Transfer-Encoding</command>.
6869 (see <xref linkend="mailmime-mechanism">).
6870 </para>
6871 </listitem>
6872 <listitem>
6873 <para>
6874 <command>fld_data.fld_id</command> is set in case of
6875 <command>Content-ID</command>. This is a string.
6876 </para>
6877 </listitem>
6878 <listitem>
6879 <para>
6880 <command>fld_data.fld_description</command> is set in case of
6881 <command>Content-Description</command>. This is a string.
6882 </para>
6883 </listitem>
6884 <listitem>
6885 <para>
6886 <command>fld_data.fld_version</command> is set in case of
6887 <command>MIME-Version</command>. This is an integer built
6888 using the following formula :
6889 <command>fld_version = major * 2^16 + minor</command>.
6890 Currenly MIME-Version is always <command>1.0</command>, this means that
6891 fld_version will always be <command>2^16</command> (in C language,
6892 this is <command>1 << 16</command>).
6893 </para>
6894 </listitem>
6895 <listitem>
6896 <para>
6897 <command>fld_data.fld_disposition</command> is set in case of
6898 <command>Content-Disposition</command>.
6899 (see <xref linkend="mailmime-disposition">).
6900 </para>
6901 </listitem>
6902 <listitem>
6903 <para>
6904 <command>fld_data.fld_language</command> is set in case of
6905 <command>Content-Language</command>.
6906 (see <xref linkend="mailmime-language">).
6907 </para>
6908 </listitem>
6909 </itemizedlist>
6910
6911 <para>
6912 <command>mailmime_field_new()</command> creates and initializes
6913 a data structure with a value.
6914 Structures given as argument are referenced by the created
6915 object and will be freed if the object is released.
6916 </para>
6917
6918 <para>
6919 <command>mailmime_field_free()</command> frees memory used by
6920 the structure and substructures will also be released.
6921 </para>
6922
6923 <example>
6924 <title>Creation and display of MIME header field</title>
6925 <programlisting role="C">
6926#include &lt;libetpan/libetpan.h&gt;
6927
6928int main(int argc, char ** argv)
6929{
6930 struct mailmime_field * field;
6931 struct mailmime_mechanism * encoding;
6932
6933 encoding = mailmime_mechanism_new(MAILMIME_MECHANISM_BASE64, NULL);
6934
6935 field = mailmime_field_new(MAILMIME_FIELD_TRANSFER_ENCODING,
6936 NULL, encoding, NULL, NULL, 0, NULL, NULL);
6937
6938 /* do the things */
6939
6940 mailmime_field_free(field);
6941}
6942
6943void display_mime_field(struct mailmime_field * field)
6944{
6945 switch (field-&gt;fld_type) {
6946 case MAILMIME_FIELD_TYPE:
6947 printf("content-type:");
6948 display_mime_content(field-&gt;fld_data.fld_content);
6949 break;
6950 case MAILMIME_FIELD_TRANSFER_ENCODING:
6951 printf("content-transfer-encoding:");
6952 display_mime_mechanism(field-&gt;fld_data.fld_encoding);
6953 break;
6954 case MAILMIME_FIELD_ID:
6955 printf("content-id: %s\n", field-&gt;fld_data.fld_id);
6956 break;
6957 case MAILMIME_FIELD_DESCRIPTION:
6958 printf("content-description: %s\n", field-&gt;fld_data.fld_description);
6959 break;
6960 case MAILMIME_FIELD_VERSION:
6961 printf("mime-version: %i.%i\n",
6962 field-&gt;version>> 16, field-&gt;fld_data.fld_version & 0xFFFF);
6963 break;
6964 case MAILMIME_FIELD_DISPOSITION:
6965 printf("content-disposition:");
6966 display_mime_disposition(field-&gt;fld_data.fld_disposition);
6967 break;
6968 case MAILMIME_FIELD_LANGUAGE:
6969 printf("content-language:");
6970 display_mime_language(field-&gt;fld_data.fld_language);
6971 break;
6972 }
6973}
6974 </programlisting>
6975 </example>
6976 </sect2>
6977
6978 <!-- mailmime_mechanism -->
6979 <sect2 id="mailmime-mechanism">
6980 <title>mailmime_mechanism - MIME transfer encoding mechanism (Content-Transfer-Encoding)</title>
6981
6982 <programlisting role="C">
6983#include &lt;libetpan/libetpan.h&gt;
6984
6985enum {
6986 MAILMIME_MECHANISM_ERROR,
6987 MAILMIME_MECHANISM_7BIT,
6988 MAILMIME_MECHANISM_8BIT,
6989 MAILMIME_MECHANISM_BINARY,
6990 MAILMIME_MECHANISM_QUOTED_PRINTABLE,
6991 MAILMIME_MECHANISM_BASE64,
6992 MAILMIME_MECHANISM_TOKEN
6993};
6994
6995struct mailmime_mechanism {
6996 int enc_type;
6997 char * enc_token;
6998};
6999
7000struct mailmime_mechanism * mailmime_mechanism_new(int enc_type, char * enc_token);
7001
7002void mailmime_mechanism_free(struct mailmime_mechanism * mechanism);
7003 </programlisting>
7004
7005 <para>
7006 This is a MIME transfer encoding mechanism description.
7007 </para>
7008
7009 <para>
7010 <command>enc_type</command> is an encoding type. The value of this field
7011 can be
7012 <command>MAILMIME_MECHANISM_7BIT</command>
7013 if mechanism is <command>7bit</command>,
7014 <command>MAILMIME_MECHANISM_8BIT</command>
7015 if mechanism is <command>8bit</command>,
7016 <command>MAILMIME_MECHANISM_BINARY</command>
7017 if mechanism is <command>binary</command>,
7018 <command>MAILMIME_MECHANISM_QUOTED_PRINTABLE</command>
7019 if mechanism is <command>quoted-printable</command>,
7020 <command>MAILMIME_MECHANISM_BASE64</command>
7021 if mechanism is <command>base64</command> or
7022 <command>MAILMIME_MECHANISM_TOKEN</command> for other.
7023 In case of <command>MAILMIME_MECHANISM_TOKEN</command>,
7024 field <command>enc_token</command> is filled in.
7025 <command>MAILMIME_MECHANISM_ERROR</command> is used internally.
7026 </para>
7027
7028 <para>
7029 <command>mailmime_mechanism_new()</command> creates and initializes
7030 a data structure with a value.
7031 Structures given as argument are referenced by the created
7032 object and will be freed if the object is released.
7033 </para>
7034
7035 <para>
7036 <command>mailmime_mechanism_free()</command> frees memory used by
7037 the structure and substructures will also be released.
7038 </para>
7039
7040 <example>
7041 <title>Creation and display of MIME transfer encoding mechanism</title>
7042 <programlisting role="C">
7043#include &lt;libetpan/libetpan.h&gt;
7044
7045int main(int argc, char ** argv)
7046{
7047 struct mailmime_mechanism * encoding;
7048
7049 encoding = mailmime_mechanism_new(MAILMIME_MECHANISM_QUOTED_PRINTABLE, NULL);
7050
7051 /* do the things */
7052
7053 mailmime_mechanism_free(encoding);
7054}
7055
7056int main(int argc, char ** argv)
7057{
7058 struct mailmime_mechanism * encoding;
7059
7060 encoding = mailmime_mechanism_new(MAILMIME_MECHANISM_TOKEN,
7061 strdup("uuencoding"));
7062
7063 /* do the things */
7064
7065 mailmime_mechanism_free(encoding);
7066}
7067
7068void display_mime_mechanism(struct mailmime_mechanism * encoding)
7069{
7070 switch (encoding-&gt;enc_type) {
7071 case MAILMIME_MECHANISM_7BIT:
7072 printf("7bit\n");
7073 break;
7074 case MAILMIME_MECHANISM_8BIT:
7075 printf("8bit\n");
7076 break;
7077 case MAILMIME_MECHANISM_BINARY:
7078 printf("binary\n");
7079 break;
7080 case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
7081 printf("quoted-printable\n");
7082 break;
7083 case MAILMIME_MECHANISM_BASE64:
7084 printf("base64\n");
7085 break;
7086 case MAILMIME_MECHANISM_TOKEN:
7087 printf("extension : %s\n", encoding-&gt;enc_token);
7088 break;
7089 }
7090}
7091 </programlisting>
7092 </example>
7093 </sect2>
7094
7095 <!-- mailmime_fields -->
7096 <sect2 id="mailmime-fields">
7097 <title>mailmime_fields - header fields</title>
7098
7099 <programlisting role="C">
7100#include &lt;libetpan/libetpan.h&gt;
7101
7102struct mailmime_fields {
7103 clist * fld_list; /* list of (struct mailmime_field *) */
7104};
7105
7106struct mailmime_fields * mailmime_fields_new(clist * fld_list);
7107
7108void mailmime_fields_free(struct mailmime_fields * fields);
7109 </programlisting>
7110
7111 <para>
7112 This is the header fields of a MIME part.
7113 </para>
7114
7115 <para>
7116 <command>fld_list</command> is the list of the header fields.
7117 Each element of the list is a <command>mailmime_field</command>
7118 (See <xref linkend="mailmime-field">).
7119 </para>
7120
7121 <para>
7122 <command>mailmime_fields_new()</command> creates and initializes
7123 a data structure with a value.
7124 Structures given as argument are referenced by the created
7125 object and will be freed if the object is released.
7126 </para>
7127
7128 <para>
7129 <command>mailmime_fields_free()</command> frees memory used by
7130 the structure and substructures will also be released.
7131 </para>
7132
7133 <example>
7134 <title>Creation and display of MIME fields</title>
7135 <programlisting role="C">
7136#include &lt;libetpan/libetpan.h&gt;
7137
7138int main(int argc, char ** argv)
7139{
7140 struct mailmime_field * field;
7141 struct mailmime_fields * fields;
7142 clist * list;
7143 struct mailmime_mechanism * encoding;
7144 struct mailmime_disposition * disposition;
7145
7146 list = clist_new();
7147
7148 encoding = mailmime_mechanism_new(MAILMIME_MECHANISM_BASE64, NULL);
7149 field = mailmime_field_new(MAILMIME_FIELD_TRANSFER_ENCODING,
7150 NULL, encoding, NULL, NULL, 0, NULL, NULL);
7151 clist_append(list, field);
7152
7153 field = mailmime_field_new(MAILMIME_FIELD_VERSION,
7154 NULL, NULL, NULL, NULL, 1 << 16, NULL, NULL);
7155 clist_append(list, field);
7156
7157 /* look at the example in mailmime_disposition to see how to
7158 build a mailmime_disposition */
7159 disposition = build_mime_disposition();
7160 field = mailmime_field_new(MAILMIME_FIELD_DISPOSITION,
7161 NULL, NULL, NULL, NULL, 0, disposition, NULL);
7162 clist_append(list, field);
7163
7164 fields = mailmime_fields_new(list);
7165
7166 /* do the things */
7167
7168 mailmime_fields_free(fields);
7169}
7170
7171void display_mime_fields(struct mailmime_fields * fields)
7172{
7173 clistiter * cur;
7174
7175 for(cur = clist_begin(fields-&gt;fld_list ; cur != NULL ;
7176 cur = clist_next(cur)) {
7177 struct mailmime_field * field;
7178
7179 field = clist_content(cur);
7180 display_field(field);
7181 }
7182}
7183 </programlisting>
7184 </example>
7185 </sect2>
7186
7187 <!-- mailmime_parameter -->
7188 <sect2 id="mailmime-parameter">
7189 <title>mailmime_parameter - MIME type parameter</title>
7190
7191 <programlisting role="C">
7192struct mailmime_parameter {
7193 char * pa_name;
7194 char * pa_value;
7195};
7196 </programlisting>
7197
7198 <para>
7199 This is the MIME type parameter in
7200 <command>Content-Type</command> MIME header
7201 field. For example, this can be
7202 <command>charset="iso-8859-1"</command>.
7203 </para>
7204
7205 <itemizedlist>
7206 <listitem>
7207 <para>
7208 <command>pa_name</command> is the name of the parameter,
7209 for example : <command>charset</command>.
7210 </para>
7211 </listitem>
7212 <listitem>
7213 <para>
7214 <command>pa_value</command> is the value of the parameter,
7215 for example : <command>iso-8859-1</command>.
7216 </para>
7217 </listitem>
7218 </itemizedlist>
7219
7220 <para>
7221 <command>mailmime_parameter_new()</command> creates and initializes
7222 a data structure with a value.
7223 Structures given as argument are referenced by the created
7224 object and will be freed if the object is released.
7225 </para>
7226
7227 <para>
7228 <command>mailmime_parameter_free()</command> frees memory used by
7229 the structure and substructures will also be released.
7230 </para>
7231
7232 <example>
7233 <title>Creation and display of MIME type parameter</title>
7234 <programlisting role="C">
7235#include &lt;libetpan/libetpan.h&gt;
7236
7237int main(int argc, char ** argv)
7238{
7239 struct mailmime_parameter * param;
7240
7241 param = mailmime_parameter_new(strdup("charset"), strdup("iso-8859-1"));
7242
7243 /* do the things */
7244
7245 mailmime_parameter_free(param);
7246}
7247
7248void display_mime_parameter(struct mailmime_parameter * param)
7249{
7250 printf("%s = %s\n", param-&gt;pa_name, param-&gt;pa_value);
7251}
7252 </programlisting>
7253 </example>
7254
7255 </sect2>
7256
7257 <!-- mailmime_type -->
7258 <sect2 id="mailmime-type">
7259 <title>mailmime_type - MIME main type</title>
7260
7261 <programlisting role="C">
7262#include &lt;libetpan/libetpan.h&gt;
7263
7264enum {
7265 MAILMIME_TYPE_ERROR,
7266 MAILMIME_TYPE_DISCRETE_TYPE,
7267 MAILMIME_TYPE_COMPOSITE_TYPE
7268};
7269
7270struct mailmime_type {
7271 int tp_type;
7272 union {
7273 struct mailmime_discrete_type * tp_discrete_type;
7274 struct mailmime_composite_type * tp_composite_type;
7275 } tp_data;
7276};
7277
7278struct mailmime_type *
7279mailmime_type_new(int tp_type,
7280 struct mailmime_discrete_type * tp_discrete_type,
7281 struct mailmime_composite_type * tp_composite_type);
7282
7283void mailmime_type_free(struct mailmime_type * type);
7284 </programlisting>
7285
7286 <para>
7287 This is the MIME main type (no subtype, no parameter).
7288 </para>
7289
7290 <itemizedlist>
7291 <listitem>
7292 <para>
7293 <command>tp_type</command>. The value of this field
7294 is either <command>MAILMIME_TYPE_DISCRETE_TYPE</command> for MIME discrete type,
7295 or <command>MAILMIME_TYPE_COMPOSITE_TYPE</command> for MIME composite type.
7296 <command>MAILMIME_TYPE_ERROR</command> is used internally.
7297 </para>
7298 </listitem>
7299 <listitem>
7300 <para>
7301 <command>tp_data.tp_discrete_type</command> is set when <command>tp_type</command>
7302 is <command>MAILMIME_TYPE_DISCRETE_TYPE</command>
7303 (see <xref linkend="mailmime-discrete-type">).
7304 </para>
7305 </listitem>
7306 <listitem>
7307 <para>
7308 <command>tp_data.tp_composite_type</command> is set when <command>tp_type</command>
7309 is <command>MAILMIME_TYPE_COMPOSITE_TYPE</command>
7310 (see <xref linkend="mailmime-composite-type">).
7311 </para>
7312 </listitem>
7313 </itemizedlist>
7314
7315 <para>
7316 <command>mailmime_discrete_type_new()</command> creates and
7317 initializes
7318 a data structure with a value.
7319 Structures given as argument are referenced by the created
7320 object and will be freed if the object is released.
7321 </para>
7322
7323 <para>
7324 <command>mailmime_discrete_type_free()</command> frees
7325 memory used by
7326 the structure and substructures will also be released.
7327 </para>
7328
7329 <example>
7330 <title>Creation and display of MIME main type</title>
7331 <programlisting role="C">
7332#include &lt;libetpan/libetpan.h&gt;
7333
7334int main(int argc, char ** argv)
7335{
7336 struct mailmime_type * type;
7337 struct mailmime_discrete_type * discrete_type;
7338
7339 discrete_type =
7340 mailmime_discrete_type_new(MAILMIME_DISCRETE_TYPE_TEXT, NULL);
7341 type = mailmime_type_new(MAILMIME_TYPE_DISCRETE_TYPE, discrete_type, NULL);
7342
7343 /* do the things */
7344
7345 mailmime_type_free(type);
7346}
7347
7348int main(int argc, char ** argv)
7349{
7350 struct mailmime_type * type;
7351 struct mailmime_composite_type * composite_type;
7352
7353 composite_type =
7354 mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MULTIPART, NULL);
7355 type = mailmime_type_new(MAILMIME_TYPE_COMPOSITE_TYPE, NULL, composite_type);
7356
7357 /* do the things */
7358
7359 mailmime_type_free(type);
7360}
7361
7362void display_mime_type(struct mailmime_type * type)
7363{
7364 printf("mime type:\n");
7365 switch (type-&gt;tp_type) {
7366 case MAILMIME_TYPE_DISCRETE_TYPE:
7367 printf("discrete type:\n");
7368 display_mime_discrete_type(type-&gt;tp_data.tp_discrete_type);
7369 break;
7370 case MAILMIME_TYPE_COMPOSITE_TYPE:
7371 printf("composite type:\n");
7372 display_mime_composite_type(type-&gt;tp_data.tp_composite_type);
7373 break;
7374 }
7375 printf("\n");
7376}
7377 </programlisting>
7378 </example>
7379 </sect2>
7380
7381 <!-- mailmime_discrete_type -->
7382 <sect2 id="mailmime-language">
7383 <title>mailmime_language - Language of MIME part</title>
7384
7385 <programlisting role="C">
7386#include &lt;libetpan/libetpan.h&gt;
7387
7388struct mailmime_language {
7389 clist * lg_list; /* atom (char *) */
7390};
7391
7392struct mailmime_language * mailmime_language_new(clist * lg_list);
7393
7394void mailmime_language_free(struct mailmime_language * lang);
7395 </programlisting>
7396
7397 <para>
7398 This is the language used in the MIME part.
7399 </para>
7400
7401 <para>
7402 <command>lg_list</command> is the list of codes of languages used
7403 in the MIME part. This is a list of strings.
7404 </para>
7405
7406 <para>
7407 <command>mailmime_language_new()</command> creates and
7408 initializes
7409 a data structure with a value.
7410 Structures given as argument are referenced by the created
7411 object and will be freed if the object is released.
7412 </para>
7413
7414 <para>
7415 <command>mailmime_language_free()</command> frees
7416 memory used by
7417 the structure and substructures will also be released.
7418 </para>
7419
7420 <example>
7421 <title>Creation and display of language of MIME part</title>
7422 <programlisting role="C">
7423#include &lt;libetpan/libetpan.h&gt;
7424
7425int main(int argc, char ** argv)
7426{
7427 struct mailmime_language * language;
7428 clist * list;
7429
7430 list = clist_new();
7431
7432 clist_append(list, strdup("fr"));
7433 clist_append(list, strdup("en"));
7434
7435 language = mailmime_language_new(list);
7436
7437 /* do the things */
7438
7439 mailmime_language_free(language);
7440}
7441
7442void display_mime_language(struct mailmime_language * language)
7443{
7444 clistiter * cur;
7445
7446 printf("languages: ");
7447 for(cur = clist_begin(language-&gt;lg_list) ; cur != NULL ;
7448 cur = clist_next(cur)) {
7449 char * name;
7450
7451 name = clist_content(cur);
7452 printf("%s ", name);
7453 }
7454 printf("\n");
7455}
7456 </programlisting>
7457 </example>
7458
7459 </sect2>
7460
7461 <!-- mailmime_data -->
7462 <sect2 id="mailmime-data">
7463 <title>mailmime_data - Content of MIME part</title>
7464
7465 <programlisting role="C">
7466#include &lt;libetpan/libetpan.h&gt;
7467
7468enum {
7469 MAILMIME_DATA_TEXT,
7470 MAILMIME_DATA_FILE,
7471};
7472
7473enum {
7474 MAILMIME_MECHANISM_ERROR,
7475 MAILMIME_MECHANISM_7BIT,
7476 MAILMIME_MECHANISM_8BIT,
7477 MAILMIME_MECHANISM_BINARY,
7478 MAILMIME_MECHANISM_QUOTED_PRINTABLE,
7479 MAILMIME_MECHANISM_BASE64,
7480 MAILMIME_MECHANISM_TOKEN
7481};
7482
7483struct mailmime_data {
7484 int dt_type;
7485 int dt_encoding;
7486 int dt_encoded;
7487 union {
7488 struct {
7489 const char * dt_data;
7490 size_t dt_length;
7491 } dt_text;
7492 char * dt_filename;
7493 } dt_data;
7494};
7495
7496struct mailmime_data * mailmime_data_new(int dt_type, int dt_encoding,
7497 int dt_encoded, const char * dt_data, size_t dt_length,
7498 char * dt_filename);
7499
7500void mailmime_data_free(struct mailmime_data * mime_ </programlisting>
7501
7502 <para>
7503 This is the content of MIME part, content of
7504 preamble or content of epilogue.
7505 </para>
7506
7507 <para>
7508 <command>dt_type</command> can be
7509 <command>MAILMIME_DATA_TEXT</command> if
7510 the content is a string in memory,
7511 <command>MAILMIME_DATA_FILE</command> if the
7512 content is in a file,
7513 </para>
7514
7515 <para>
7516 <command>dt_encoding</command> is the encoding mechanism
7517 of the part. The value of this field can be
7518 <command>MAILMIME_MECHANISM_7BIT</command> if mechanism is
7519 <command>7bit</command>,
7520 <command>MAILMIME_MECHANISM_8BIT</command> if mechanism is
7521 <command>8bit</command>,
7522 <command>MAILMIME_MECHANISM_BINARY</command> if mechanism is
7523 <command>binary</command>,
7524 <command>MAILMIME_MECHANISM_QUOTED_PRINTABLE</command> if
7525 mechanism is <command>quoted-printable</command>,
7526 <command>MAILMIME_MECHANISM_BASE64</command> if mechanism is
7527 <command>base64</command> or
7528 <command>MAILMIME_MECHANISM_TOKEN</command> for other. If
7529 <command>MAILMIME_MECHANISM_TOKEN</command>, the part will
7530 be considered as binary.
7531 <command>MAILMIME_MECHANISM_ERROR</command> is used internally.
7532 </para>
7533
7534 <para>
7535 <command>dt_encoded</command> is set to 1 if the part is
7536 already encoded with the mechanism given in
7537 <command>dt_encoding</command>. It is set to 0 if the part
7538 is already decoded or if it is necessary to encode that part
7539 before rendering it.
7540 </para>
7541
7542 <para>
7543 <command>dt_data.dt_text.dt_data</command> is a pointer to the
7544 content of the part and <command>dt_data.dt_text.dt_length</command>
7545 is the length of the data if <command>dt_type</command> is
7546 <command>MAILMIME_DATA_TEXT</command>.
7547 </para>
7548
7549 <para>
7550 <command>dt_data.dt_filename</command> is the name of the file if
7551 <command>dt_type</command> is <command>MAILMIME_DATA_FILE</command>.
7552 </para>
7553
7554 <para>
7555 <command>mailmime_data_new()</command> creates and
7556 initializes
7557 a data structure with a value.
7558 Structures given as argument are referenced by the created
7559 object and will be freed if the object is released.
7560 </para>
7561
7562 <para>
7563 <command>mailmime_data_free()</command> frees
7564 memory used by
7565 the structure and substructures will also be released.
7566 </para>
7567
7568 <example>
7569 <title>Creation and display of MIME part content</title>
7570
7571 <programlisting role="C">
7572#include &lt;libetpan/libetpan.h&gt;
7573
7574/* build data with a string */
7575
7576int main(int argc, char ** argv)
7577{
7578 struct mailmime_data * data;
7579
7580 data = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_BASE64,
7581 0, "foo bar", 7, NULL);
7582
7583 /* do the things */
7584
7585 mailmime_data_free(data);
7586}
7587
7588/* build data with a file */
7589
7590int main(int argc, char ** argv)
7591{
7592 struct mailmime_data * data;
7593
7594 data = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_BASE64,
7595 0, NULL, 0, strdup("foo.txt"));
7596
7597 /* do the things */
7598
7599 mailmime_data_free(data);
7600}
7601
7602void display_mime_data(struct mailmime_data * data)
7603{
7604 switch (data-&gt;dt_encoding) {
7605 case MAILMIME_MECHANISM_7BIT:
7606 printf("7bit\n");
7607 break;
7608 case MAILMIME_MECHANISM_8BIT:
7609 printf("8bit\n");
7610 break;
7611 case MAILMIME_MECHANISM_BINARY:
7612 printf("binary\n");
7613 break;
7614 case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
7615 printf("quoted-printable\n");
7616 break;
7617 case MAILMIME_MECHANISM_BASE64:
7618 printf("base64\n");
7619 break;
7620 case MAILMIME_MECHANISM_TOKEN:
7621 printf("other\n");
7622 break;
7623 }
7624
7625 if (data-&gt;dt_encoded)
7626 printf("already encoded\n");
7627 else
7628 printf("not encoded\n");
7629
7630 switch (data-&gt;dt_type) {
7631 MAILMIME_DATA_TEXT:
7632 printf("data : %p %i\n", data->dt_data.dt_text.dt_data,
7633 data->dt_data.dt_text.dt_length);
7634 break;
7635 MAILMIME_DATA_FILE,
7636 printf("data (file) : %s\n", data->dt_data.dt_filename);
7637 break;
7638 }
7639}
7640 </programlisting>
7641 </example>
7642 </sect2>
7643
7644 <!-- mailmime -->
7645 <sect2 id="mailmime">
7646 <title>mailmime - MIME part</title>
7647
7648 <programlisting role="C">
7649#include &lt;libetpan/libetpan.h&gt;
7650
7651enum {
7652 MAILMIME_NONE,
7653 MAILMIME_SINGLE,
7654 MAILMIME_MULTIPLE,
7655 MAILMIME_MESSAGE,
7656};
7657
7658struct mailmime {
7659 /* parent information */
7660 int mm_parent_type;
7661 struct mailmime * mm_parent;
7662 clistiter * mm_multipart_pos;
7663
7664 int mm_type;
7665 const char * mm_mime_start;
7666 size_t mm_length;
7667
7668 struct mailmime_fields * mm_mime_fields;
7669 struct mailmime_content * mm_content_type;
7670
7671 struct mailmime_data * mm_body;
7672 union {
7673 /* single part */
7674 struct mailmime_data * mm_single; /* XXX - was body */
7675
7676 /* multi-part */
7677 struct {
7678 struct mailmime_data * mm_preamble;
7679 struct mailmime_data * mm_epilogue;
7680 clist * mm_mp_list;
7681 } mm_multipart;
7682
7683 /* message */
7684 struct {
7685 struct mailimf_fields * mm_fields;
7686 struct mailmime * mm_msg_mime;
7687 } mm_message;
7688
7689 } mm_data;
7690};
7691
7692struct mailmime * mailmime_new(int mm_type,
7693 const char * mm_mime_start, size_t mm_length,
7694 struct mailmime_fields * mm_mime_fields,
7695 struct mailmime_content * mm_content_type,
7696 struct mailmime_data * mm_body,
7697 struct mailmime_data * mm_preamble,
7698 struct mailmime_data * mm_epilogue,
7699 clist * mm_mp_list,
7700 struct mailimf_fields * mm_fields,
7701 struct mailmime * mm_msg_mime);
7702
7703void mailmime_free(struct mailmime * mime);
7704 </programlisting>
7705
7706 <para>
7707 This describes the MIME structure of a message or a subpart
7708 of a message.
7709 </para>
7710
7711 <sect3>
7712 <title>common</title>
7713
7714 <itemizedlist>
7715 <listitem>
7716 <para>
7717 <command>mm_parent_type</command>. MIME part type can be
7718 single part, multipart or message part. This describes the MIME part
7719 type of the parent. The value can be
7720 <command>MAILMIME_NONE</command> if there is no parent part,
7721 <command>MAILMIME_SINGLE</command> if parent is a single part,
7722 <command>MAILMIME_MULTIPLE</command> if parent is a multipart,
7723 <command>MAILMIME_MESSAGE</command> if parent is a mesage part.
7724 </para>
7725 </listitem>
7726
7727 <listitem>
7728 <para>
7729 <command>mm_parent</command> is the parent MIME structure.
7730 </para>
7731 </listitem>
7732
7733 <listitem>
7734 <para>
7735 <command>mm_multipart_pos</command>. In the case the parent
7736 is a multipart. This is the position in the list of children
7737 of the parent. This position is given by a
7738 <command>clisiter *</command>.
7739 </para>
7740 </listitem>
7741
7742 <listitem>
7743 <para>
7744 <command>mm_type</command>. This describes the MIME part type
7745 of this part. The value can be
7746 <command>MAILMIME_SINGLE</command> if this is a single part,
7747 <command>MAILMIME_MULTIPLE</command> if this is a multipart,
7748 <command>MAILMIME_MESSAGE</command> if this is a mesage part.
7749 </para>
7750 </listitem>
7751
7752 <listitem>
7753 <para>
7754 <command>mm_mime_start</command>. This is used mostly internally.
7755 This gives the beginning of the header of the MIME part, when this
7756 is parsed from a string in memory.
7757 </para>
7758 </listitem>
7759
7760
7761 <listitem>
7762 <para>
7763 <command>mm_length</command>. This gives the length of the MIME part,
7764 including the MIME header fields.
7765 </para>
7766 </listitem>
7767
7768 <listitem>
7769 <para>
7770 <command>mm_mime_fields</command> is the list of parsed MIME headers
7771 of this part. <command>Content-Type</command> must be excluded and stored
7772 in <command>mm_content_type</command> instead
7773 (see <xref linkend="mailmime-fields">).
7774 </para>
7775 </listitem>
7776
7777
7778 <listitem>
7779 <para>
7780 <command>mm_content_type</command> is the parsed
7781 <command>Content-Type</command> field
7782 (see <xref linkend="mailmime-content">).
7783 </para>
7784 </listitem>
7785
7786
7787 <listitem>
7788 <para>
7789 <command>mm_body</command> is the content of the MIME part
7790 (excluding MIME header), when it is parsed from a string
7791 in memory
7792 (see <xref linkend="mailmime-data">).
7793 </para>
7794 </listitem>
7795 </itemizedlist>
7796 </sect3>
7797
7798 <sect3>
7799 <title>single part</title>
7800
7801 <itemizedlist>
7802 <listitem>
7803 <para>
7804 When the part is a single part (<command>mm_type</command>
7805 is <command>MAILMIME_SINGLE</command>). The following fields
7806 are valid.
7807 </para>
7808 </listitem>
7809
7810 <listitem>
7811 <para>
7812 <command>mm_data.mm_single</command> is the content of the
7813 MIME part (excluding MIME header), when it is parsed from a string
7814 in memory. This must have the same
7815 value as <command>mm_body</command> when it is set
7816 (see <xref linkend="mailmime-data">).
7817 </para>
7818 </listitem>
7819 </itemizedlist>
7820 </sect3>
7821
7822 <sect3>
7823 <title>multipart</title>
7824
7825 <itemizedlist>
7826 <listitem>
7827 <para>
7828 When the part is a multipart (<command>mm_type</command>
7829 is <command>MAILMIME_MULTIPLE</command>). The following fields
7830 are valid.
7831 </para>
7832 </listitem>
7833
7834 <listitem>
7835 <para>
7836 <command>mm_data.mm_multipart.mm_preamble</command>
7837 is the content of the preamble of the multipart
7838 (see <xref linkend="mailmime-data">).
7839 </para>
7840 </listitem>
7841
7842 <listitem>
7843 <para>
7844 <command>mm_data.mm_multipart.mm_epilogue</command>
7845 is the content of the epilogue of the multipart
7846 (see <xref linkend="mailmime-data">).
7847 </para>
7848 </listitem>
7849
7850 <listitem>
7851 <para>
7852 <command>mm_data.mm_multipart.mm_mp_list</command>
7853 is the list of sub parts
7854 </para>
7855 </listitem>
7856 </itemizedlist>
7857 </sect3>
7858
7859 <sect3>
7860 <title>message part</title>
7861
7862 <itemizedlist>
7863 <listitem>
7864 <para>
7865 When the part is a message (<command>mm_type</command>
7866 is <command>MAILMIME_MESSAGE</command>). The following fields
7867 are valid.
7868 </para>
7869 </listitem>
7870
7871 <listitem>
7872 <para>
7873 <command>mm_data.mm_message.mm_fields</command> is the list of
7874 the header fields of the message
7875 (see <xref linkend="mailimf-fields">).
7876 </para>
7877 </listitem>
7878
7879 <listitem>
7880 <para>
7881 <command>mm_data.mm_message.mm_msg_mime</command> is
7882 the subpart
7883 of the message part.
7884 </para>
7885 </listitem>
7886 </itemizedlist>
7887 </sect3>
7888
7889 <sect3>
7890 <title>constructor and destructor</title>
7891
7892 <para>
7893 <command>mailmime_new()</command> creates and
7894 initializes
7895 a data structure with a value.
7896 Structures given as argument are referenced by the created
7897 object and will be freed if the object is released.
7898 </para>
7899
7900 <para>
7901 <command>mailmime_free()</command> frees
7902 memory used by
7903 the structure and substructures will also be released.
7904 </para>
7905
7906 <example>
7907 <title>Creation and display of MIME part</title>
7908
7909 <programlisting role="C">
7910#include &lt;libetpan/libetpan.h&gt;
7911
7912/* build one single MIME part */
7913
7914int main(int argc, char ** argv)
7915{
7916 struct mailmime * mime;
7917 struct mailimf_fields * fields;
7918 struct mailmime_fields * mime_fields;
7919 struct mailmime_content * content_type;
7920 struct mailmime_data * body;
7921
7922 /* look at the example in mailimf_fields to see how to
7923 build a mailimf_fields */
7924 fields = build_fields();
7925
7926 /* look at the example in mailmime_fields to see how to
7927 build a mailmime_fields */
7928 mime_fields = build_mime_fields();
7929
7930 /* look at the example in mailmime_content to see how to
7931 build a mailmime_content */
7932 content_type = build_mime_content();
7933
7934 body = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_8BIT, 0,
7935 "foo", 3, NULL);
7936
7937 mime = mailmime_new(MAILMIME_SINGLE,
7938 NULL, 0, fields, mime_fields, content_type,
7939 body, NULL, NULL, NULL, NULL, NULL);
7940
7941 /* do the things */
7942
7943 mailmime_free(mime);
7944}
7945
7946/* build one single MIME part */
7947
7948int main(int argc, char ** argv)
7949{
7950 struct mailmime * mime;
7951 struct mailimf_fields * fields;
7952 struct mailmime_fields * mime_fields;
7953 struct mailmime_content * content_type;
7954 char * str;
7955 struct mailmime_data * body;
7956
7957 /* look at the example in mailimf_fields to see how to
7958 build a mailimf_fields */
7959 fields = build_fields();
7960
7961 /* look at the example in mailmime_fields to see how to
7962 build a mailmime_fields */
7963 mime_fields = build_mime_fields();
7964
7965 /* look at the example in mailmime_content to see how to
7966 build a mailmime_content */
7967 content_type = build_mime_content();
7968
7969 str = malloc(4);
7970 strcpy(str, "foo");
7971
7972 body = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_8BIT, 0,
7973 str, 3, NULL);
7974
7975 mime = mailmime_new(MAILMIME_SINGLE,
7976 NULL, 0, fields, mime_fields, content_type,
7977 body, NULL, NULL, NULL, NULL, NULL);
7978
7979 /* do the things */
7980
7981 mailmime_free(mime);
7982 free(str);
7983}
7984
7985/* build a MIME part with a sub-message */
7986
7987int main(int argc, char ** argv)
7988{
7989 struct mailmime * mime;
7990 struct mailimf_fields * fields;
7991 struct mailmime_fields * mime_fields;
7992 struct mailmime_content * content_type;
7993 char * str;
7994 struct mailmime_type * type;
7995 struct mailmime_composite_type * composite_type;
7996
7997 /* look at the example in mailimf_fields to see how to
7998 build a mailimf_fields */
7999 fields = build_fields();
8000
8001 /* look at the example in mailmime_fields to see how to
8002 build a mailmime_fields */
8003 mime_fields = build_mime_fields();
8004
8005 composite_type =
8006 mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MESSAGE, NULL);
8007 type = mailmime_type_new(MAILMIME_TYPE_COMPOSITE_TYPE, NULL,
8008 composite_type);
8009 content_type = mailmime_content_new(type, strdup("rfc2822"), NULL);
8010
8011 /* build_mime_message() is a function that will build a mime message part */
8012 sub_mime = build_mime_message();
8013
8014 mime = mailmime_new(MAILMIME_MESSAGE,
8015 NULL, 0, fields, mime_fields, content_type,
8016 NULL, NULL, NULL, NULL, sub_mime, NULL);
8017
8018 /* do the things */
8019
8020 mailmime_free(mime);
8021}
8022
8023/* build a MIME part with a sub-message (given by a string) */
8024
8025
8026int main(int argc, char ** argv)
8027{
8028 struct mailmime * mime;
8029 struct mailimf_fields * fields;
8030 struct mailmime_fields * mime_fields;
8031 struct mailmime_content * content_type;
8032 char * str;
8033 struct mailmime_data * msg_content;
8034 struct mailmime_type * type;
8035 struct mailmime_composite_type * composite_type;
8036
8037 /* look at the example in mailimf_fields to see how to
8038 build a mailimf_fields */
8039 fields = build_fields();
8040
8041 /* look at the example in mailmime_fields to see how to
8042 build a mailmime_fields */
8043 mime_fields = build_mime_fields();
8044
8045 composite_type =
8046 mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MESSAGE, NULL);
8047 type = mailmime_type_new(MAILMIME_TYPE_COMPOSITE_TYPE, NULL,
8048 composite_type);
8049 content_type = mailmime_content_new(type, strdup("rfc2822"), NULL);
8050
8051 str = malloc(sizeof(SUB_MESSAGE));
8052 strcpy(str, SUB_MESSAGE);
8053
8054 msg_content = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_8BIT, 0,
8055 str, sizeof(SUB_MESSAGE), NULL);
8056
8057 mime = mailmime_new(MAILMIME_MESSAGE,
8058 NULL, 0, fields, mime_fields, content_type,
8059 NULL, NULL, NULL, NULL, NULL, msg_content);
8060
8061 /* do the things */
8062
8063 mailmime_free(mime);
8064 free(str);
8065}
8066
8067/* build a multipart message */
8068
8069
8070
8071int main(int argc, char ** argv)
8072{
8073 struct mailmime * mime;
8074 struct mailimf_fields * fields;
8075 struct mailmime_fields * mime_fields;
8076 struct mailmime_content * content_type;
8077 struct mailmime_type * type;
8078 struct mailmime_composite_type * composite_type;
8079 struct mailmime_data * body;
8080 struct mailmime_data * preamble;
8081 struct mailmime_data * epilogue;
8082 clist * list;
8083
8084 /* look at the example in mailimf_fields to see how to
8085 build a mailimf_fields */
8086 fields = build_fields();
8087
8088 /* look at the example in mailmime_fields to see how to
8089 build a mailmime_fields */
8090 mime_fields = build_mime_fields();
8091
8092 composite_type =
8093 mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MULTIPART, NULL);
8094 type = mailmime_type_new(MAILMIME_TYPE_COMPOSITE_TYPE, NULL,
8095 composite_type);
8096 content_type = mailmime_content_new(type, strdup("mixed"), NULL);
8097
8098 list = clist_new();
8099 /* build_mime_message() is a function that will build a mime message part */
8100 sub_mime = build_mime_message();
8101 clist_append(list, sub_mime);
8102 sub_mime = build_mime_message();
8103 clist_append(list, sub_mime);
8104
8105 preamble = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_8BIT, 0,
8106 PREAMBLE, sizeof(PREAMBLE), NULL);
8107
8108 epilogue = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_8BIT, 0,
8109 EPILOGUE, sizeof(EPILOGUE), NULL);
8110
8111 mime = mailmime_new(MAILMIME_SINGLE,
8112 NULL, 0, fields, mime_fields, content_type,
8113 NULL, preamble, epilogue, list, NULL, NULL);
8114
8115 /* do the things */
8116
8117 mailmime_free(mime);
8118}
8119
8120/* display mime part info */
8121
8122void display_mime(struct mailmime * mime)
8123{
8124 clistiter * cur;
8125
8126 switch (mime-&gt;mm_type) {
8127 case MAILMIME_SINGLE:
8128 printf("single part\n");
8129 break;
8130 case MAILMIME_MULTIPLE:
8131 printf("multipart\n");
8132 break;
8133 case MAILMIME_MESSAGE:
8134 printf("message\n");
8135 break;
8136 }
8137
8138 printf("part : %p, length : %i\n",
8139 mime-&gt;mm_mime_start, mime-&gt;mm_length);
8140 printf("\n");
8141
8142 if (mime-&gt;mm_mime_fields != NULL) {
8143 printf("MIME headers :\n");
8144 display_mime_fields(mime->mm_mime_fields);
8145 printf("\n");
8146 }
8147
8148 printf("content type :\n");
8149 display_content(mime-&gt;mm_content_type);
8150 printf("\n");
8151
8152 switch (mime-&gt;mm_type) {
8153 case MAILMIME_SINGLE:
8154 display_mime_data(mime-&gt;mm_data.mm_single);
8155 break;
8156
8157 case MAILMIME_MULTIPLE:
8158 if (mime-&gt;mm_data.mm_multipart.mm_preamble) {
8159 printf("preamble :\n");
8160 display_mime_data(mime-&gt;mm_data.mm_multipart.mm_preamble);
8161 printf("\n");
8162 }
8163
8164 for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ;
8165 cur != NULL ; cur = clist_next(cur)) {
8166 display_mime(clist_content(cur));
8167 }
8168
8169 if (mime-&gt;mm_data.mm_multipart.mm_epilogue) {
8170 printf("epilogue :\n");
8171 display_mime_data(mime-&gt;mm_data.mm_multipart.mm_epilogue);
8172 printf("\n");
8173 }
8174 break;
8175
8176 case MAILMIME_MESSAGE:
8177 if (mime-&gt;mm_data.mm_message.mm_fields) {
8178 printf("headers :\n");
8179 display_field(mime-&gt;mm_data.mm_message.mm_msg_fields);
8180 printf("\n");
8181
8182 if (mime-&gt;mm_data.mm_message.mm_msg_mime != NULL) {
8183 printf("sub message %p :\n",
8184 mime-&gt;mm_data.mm_message.mm_msg_mime);
8185 display_mime(mime-&gt;mm_data.mm_message.mm_msg_mime);
8186 printf("end of sub message %p\n",
8187 mime-&gt;mm_data.mm_message.mm_msg_mime);
8188 }
8189 break;
8190 }
8191}
8192 </programlisting>
8193 </example>
8194
8195 </sect3>
8196
8197 </sect2>
8198
8199 <!-- mailmime_disposition -->
8200 <sect2 id="mailmime-disposition">
8201 <title>mailmime_disposition - MIME disposition information (Content-Disposition)</title>
8202
8203 <programlisting role="C">
8204#include &lt;libetpan/libetpan.h&gt;
8205
8206struct mailmime_disposition {
8207 struct mailmime_disposition_type * dsp_type;
8208 clist * dsp_parms; /* struct mailmime_disposition_parm */
8209};
8210 </programlisting>
8211
8212 <para>
8213 This is the parsed <command>Content-Disposition</command>
8214 header field.
8215 </para>
8216
8217 <itemizedlist>
8218 <listitem>
8219 <para>
8220 <command>dsp_type</command> is the type of disposition
8221 (see <xref linkend="mailmime-disposition-type">).
8222 </para>
8223 </listitem>
8224
8225 <listitem>
8226 <para>
8227 <command>dsp_parms</command> is the list of parameters
8228 of <command>Content-Disposition</command> header field.
8229 Each element is of type <command>mailmime_disposition_parm</command>
8230 (see <xref linkend="mailmime-disposition-parm">).
8231 </para>
8232 </listitem>
8233 </itemizedlist>
8234
8235 <example>
8236 <title>Creation and display of MIME disposition information</title>
8237 <programlisting role="C">
8238#include &lt;libetpan/libetpan.h&gt;
8239
8240int main(int argc, char ** argv)
8241{
8242 struct mailmime_disposition * disposition;
8243 struct mailmime_disposition_type * disposition_type;
8244 clist * disposition_parms;
8245 struct mailmime_disposition_parm * param;
8246
8247 disposition_type =
8248 mailmime_disposition_type_new(MAILMIME_DISPOSITION_TYPE_ATTACHMENT, NULL);
8249
8250 disposition_parms = clist_new();
8251 param = mailmime_disposition_parm_new(MAILMIME_DISPOSITION_PARM_FILENAME,
8252 strdup("foo.txt"), NULL,
8253 NULL, NULL, -1, NULL);
8254 clist_append(disposition_parms, param);
8255
8256 disposition = mailmime_disposition_new(disposition_type, disposition_parms);
8257
8258 /* do the things */
8259
8260 mailmime_disposition_free(disposition);
8261}
8262
8263void display_mime_disposition(struct mailmime_disposition * disposition)
8264{
8265 clistiter * cur;
8266
8267 printf("disposition type:\n");
8268 display_mailmime_disposition_type(disposition-&gt;dsp_type);
8269 printf("\n");
8270 printf("disposition parameters:\n");
8271 for(cur = clist_begin(disposition-&gt;dsp_parms) ;
8272 cur != NULL ; cur = clist_next(cur)) {
8273 struct mailmime_parm * param;
8274
8275 param = clist_content(cur);
8276 display_mime_disposition_parm(param);
8277 }
8278 printf("\n");
8279}
8280
8281 </programlisting>
8282 </example>
8283 </sect2>
8284
8285 <!-- mailmime_disposition_type -->
8286 <sect2 id="mailmime-disposition-type">
8287 <title>mailmime_disposition_type - Type of MIME disposition</title>
8288
8289 <programlisting role="C">
8290#include &lt;libetpan/libetpan.h&gt;
8291
8292enum {
8293 MAILMIME_DISPOSITION_TYPE_ERROR,
8294 MAILMIME_DISPOSITION_TYPE_INLINE,
8295 MAILMIME_DISPOSITION_TYPE_ATTACHMENT,
8296 MAILMIME_DISPOSITION_TYPE_EXTENSION
8297};
8298
8299struct mailmime_disposition_type {
8300 int dsp_type;
8301 char * dsp_extension;
8302};
8303 </programlisting>
8304
8305 <para>
8306 This is the type of MIME disposition.
8307 Parsed <command>Content-Disposition</command> field without
8308 parameters.
8309 </para>
8310
8311 <para>
8312 <command>dsp_type</command> is the type of disposition.
8313 The value can be
8314 <command>MAILMIME_DISPOSITION_TYPE_INLINE</command>
8315 if MIME disposition is inline,
8316 <command>MAILMIME_DISPOSITION_TYPE_ATTACHMENT</command>
8317 if MIME disposition is attachment,
8318 <command>MAILMIME_DISPOSITION_TYPE_EXTENSION</command>
8319 for other. In this case, <command>dsp_extension</command> must be
8320 set.
8321 <command>MAILMIME_DISPOSITION_TYPE_ERROR</command> is used internally.
8322 </para>
8323
8324 <example>
8325 <title>Creation and display of MIME disposition type</title>
8326 <programlisting role="C">
8327#include &lt;libetpan/libetpan.h&gt;
8328
8329/* standard disposition type */
8330
8331int main(int argc, char ** argv)
8332{
8333 struct mailmime_disposition_type * disposition_type;
8334
8335 disposition_type =
8336 mailmime_disposition_type_new(MAILMIME_DISPOSITION_TYPE_ATTACHMENT, NULL);
8337
8338 /* do the things */
8339
8340 mailmime_disposition_type_free(disposition_type);
8341}
8342
8343/* disposition type extension */
8344
8345int main(int argc, char ** argv)
8346{
8347 struct mailmime_disposition_type * disposition_type;
8348
8349 disposition_type =
8350 mailmime_disposition_type_new(MAILMIME_DISPOSITION_TYPE_EXTENSION,
8351 strdup("mydisposition"));
8352
8353 /* do the things */
8354
8355 mailmime_disposition_type_free(disposition_type);
8356}
8357
8358void display_mime_disposition_type(struct mailmime_disposition_type * disposition_type)
8359{
8360 switch (disposition-&gt;dsp_type) {
8361 case MAILMIME_DISPOSITION_TYPE_INLINE:
8362 printf("inline\n");
8363 break;
8364 case MAILMIME_DISPOSITION_TYPE_ATTACHMENT:
8365 printf("attachment\n");
8366 break;
8367 case MAILMIME_DISPOSITION_TYPE_EXTENSION:
8368 printf("extension : %s\n", disposition_type-&gt;dsp_extension);
8369 break;
8370 }
8371}
8372 </programlisting>
8373 </example>
8374 </sect2>
8375
8376 <!-- mailmime_disposition_parm -->
8377 <sect2 id="mailmime-disposition-parm">
8378 <title>mailmime_disposition_parm - MIME disposition parameter</title>
8379
8380 <programlisting role="C">
8381#include &lt;libetpan/libetpan.h&gt;
8382
8383enum {
8384 MAILMIME_DISPOSITION_PARM_FILENAME,
8385 MAILMIME_DISPOSITION_PARM_CREATION_DATE,
8386 MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE,
8387 MAILMIME_DISPOSITION_PARM_READ_DATE,
8388 MAILMIME_DISPOSITION_PARM_SIZE,
8389 MAILMIME_DISPOSITION_PARM_PARAMETER
8390};
8391
8392struct mailmime_disposition_parm {
8393 int pa_type;
8394 union {
8395 char * pa_filename;
8396 char * pa_creation_date;
8397 char * pa_modification_date;
8398 char * pa_read_date;
8399 size_t pa_size;
8400 struct mailmime_parameter * pa_parameter;
8401 } pa_data;
8402};
8403 </programlisting>
8404
8405 <para>
8406 This is a parameter of MIME disposition information. For
8407 example, this can be
8408 <command>filename="foo.jpg"</command>.
8409 </para>
8410
8411 <itemizedlist>
8412 <listitem>
8413 <para>
8414 <command>pa_type</command> is the type of
8415 disposition. The value can be
8416 <command>MAILMIME_DISPOSITION_PARM_FILENAME</command>
8417 for a filename parameter,
8418 <command>MAILMIME_DISPOSITION_PARM_CREATION_DATE</command>
8419 for a creation date parameter,
8420 <command>MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE</command>
8421 for a modification date parameter,
8422 <command>MAILMIME_DISPOSITION_PARM_READ_DATE</command>
8423 for a last read date parameter,
8424 <command>MAILMIME_DISPOSITION_PARM_SIZE</command>
8425 for a file size parameter or
8426 <command>MAILMIME_DISPOSITION_PARM_PARAMETER</command>
8427 for other parameters.
8428 </para>
8429 </listitem>
8430
8431 <listitem>
8432 <para>
8433 <command>pa_data.pa_filename</command> is the filename
8434 parameter when <command>pa_type</command> is
8435 <command>MAILMIME_DISPOSITION_PARM_FILENAME</command>
8436 This is a string containing the name of the
8437 file.
8438 </para>
8439 </listitem>
8440 <listitem>
8441 <para>
8442 <command>pa_data.pa_creation_date</command> is the
8443 creation date parameter when <command>pa_type</command> is
8444 <command>MAILMIME_DISPOSITION_PARM_CREATION_DATE</command>.
8445 This is a string containing the formatted creation date.
8446 </para>
8447 </listitem>
8448
8449 <listitem>
8450 <para>
8451 <command>pa_data.pa_modification_date</command> is the
8452 modification date parameter when <command>pa_type</command> is
8453 <command>MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE</command>.
8454 This is a string containing the formatted modification date.
8455 </para>
8456 </listitem>
8457
8458 <listitem>
8459 <para>
8460 <command>pa_data.pa_read_date</command> is the
8461 last read date parameter when <command>pa_type</command> is
8462 <command>MAILMIME_DISPOSITION_PARM_READ_DATE</command>.
8463 This is a string containing the formatted last read date.
8464 </para>
8465 </listitem>
8466
8467 <listitem>
8468 <para>
8469 <command>pa_data.pa_size</command> is the size
8470 parameter when <command>pa_type</command> is
8471 <command>MAILMIME_DISPOSITION_PARM_SIZE</command>.
8472 This gives the size of the file.
8473 </para>
8474 </listitem>
8475
8476 <listitem>
8477 <para>
8478 <command>pa_data.pa_parameter</command> is the
8479 name and the value of the parameter when
8480 <command>pa_type</command> is
8481 <command>MAILMIME_DISPOSITION_PARM_PARAMETER</command>
8482 (see <xref linkend="mailmime-parameter">)
8483 </para>
8484 </listitem>
8485 </itemizedlist>
8486
8487 <example>
8488 <title>Creation and display of MIME disposition
8489 parameter</title>
8490
8491 <programlisting role="C">
8492int main(int argc, char ** argv)
8493{
8494 struct mailmime_disposition_parm * param;
8495
8496 disposition_parms = clist_new();
8497 param = mailmime_disposition_parm_new(MAILMIME_DISPOSITION_PARM_FILENAME,
8498 strdup("foo.txt"), NULL,
8499 NULL, NULL, -1, NULL);
8500 /* do the things */
8501
8502 mailmime_disposition_parm_free(param);
8503}
8504
8505void display_mime_dsp_parm(struct mailmime_disposition_parm * param)
8506{
8507 switch (param-&gt;pa_type) {
8508 case MAILMIME_DISPOSITION_PARM_FILENAME:
8509 printf("filename: %s\n", param-&gt;pa_data.pa_filename);
8510 break;
8511 case MAILMIME_DISPOSITION_PARM_CREATION_DATE:
8512 printf("creation date: %s\n", param-&gt;pa_data.pa_creation_date);
8513 break;
8514 case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE:
8515 printf("modification date: %s\n", param-&gt;pa_data.pa_modification_date);
8516 break;
8517 case MAILMIME_DISPOSITION_PARM_READ_DATE:
8518 printf("read date: %s\n", param-&gt;pa_data.pa_read_date);
8519 break;
8520 case MAILMIME_DISPOSITION_PARM_SIZE:
8521 printf("size: %lu\n", (unsigned long) param-&gt;pa_data.pa_size);
8522 break;
8523 case MAILMIME_DISPOSITION_PARM_PARAMETER:
8524 printf("MIME disposition param:\n");
8525 display_mime_parameter(param-&gt;pa_data.pa_parameter);
8526 break;
8527 }
8528}
8529 </programlisting>
8530 </example>
8531 </sect2>
8532
8533 <!-- mailmime_single_fields -->
8534 <sect2 id="mailmime-single-fields">
8535 <title>mailmime_single_fields - MIME headers</title>
8536
8537
8538 <programlisting role="C">
8539#include &lt;libetpan/libetpan.h&gt;
8540
8541struct mailmime_single_fields {
8542 struct mailmime_content * fld_content;
8543 char * fld_content_charset;
8544 char * fld_content_boundary;
8545 char * fld_content_name;
8546 struct mailmime_mechanism * fld_encoding;
8547 char * fld_id;
8548 char * fld_description;
8549 uint32_t fld_version;
8550 struct mailmime_disposition * fld_disposition;
8551 char * fld_disposition_filename;
8552 char * fld_disposition_creation_date;
8553 char * fld_disposition_modification_date;
8554 char * fld_disposition_read_date;
8555 size_t fld_disposition_size;
8556 struct mailmime_language * fld_language;
8557};
8558
8559struct mailmime_single_fields *
8560mailmime_single_fields_new(struct mailmime_fields * fld_fields,
8561 struct mailmime_content * fld_content);
8562
8563void mailmime_single_fields_free(struct mailmime_single_fields *
8564 single_fields);
8565
8566void mailmime_single_fields_init(struct mailmime_single_fields * single_fields,
8567 struct mailmime_fields * fld_fields,
8568 struct mailmime_content * fld_content);
8569 </programlisting>
8570
8571 <para>
8572 <command>mailmime_fields</command> (see <xref
8573 linkend="mailmime-fields">) is the native structure
8574 that MIME module will use, this module will provide an easier
8575 structure to use when
8576 parsing fields. <command>mailmime_single_fields</command> is
8577 an easier structure to get parsed fields, rather than
8578 iteration over the list of fields.
8579 </para>
8580
8581 <itemizedlist>
8582 <listitem>
8583 <para>
8584 <command>fld_content</command> is the MIME content type
8585 (see <xref linkend="mailmime-content">).
8586 </para>
8587 </listitem>
8588 <listitem>
8589 <para>
8590 <command>fld_content_charset</command> is the value
8591 of the MIME type parameter <command>charset</command>.
8592 </para>
8593 </listitem>
8594 <listitem>
8595 <para>
8596 <command>fld_content_boundary</command> is the value
8597 of the MIME type parameter <command>boundary</command>.
8598 </para>
8599 </listitem>
8600 <listitem>
8601 <para>
8602 <command>fld_content_name</command> is the value
8603 of the MIME type parameter <command>name</command>.
8604 </para>
8605 </listitem>
8606 <listitem>
8607 <para>
8608 <command>fld_encoding</command> is the MIME encoding
8609 mechanism used
8610 (see <xref linkend="mailmime-mechanism">).
8611 </para>
8612 </listitem>
8613 <listitem>
8614 <para>
8615 <command>fld_id</command> is the content of the field
8616 <command>Content-ID</command>.
8617 </para>
8618 </listitem>
8619 <listitem>
8620 <para>
8621 <command>fld_description</command> is the content of the field
8622 <command>Content-Description</command>.
8623 </para>
8624 </listitem>
8625 <listitem>
8626 <para>
8627 <command>fld_version</command> is the version of MIME
8628 in use.
8629 </para>
8630 </listitem>
8631 <listitem>
8632 <para>
8633 <command>fld_disposition</command> is the MIME
8634 disposition information
8635 (see <xref linkend="mailmime-disposition">).
8636 </para>
8637 </listitem>
8638 <listitem>
8639 <para>
8640 <command>fld_disposition_filename</command> is
8641 the <command>filename</command> parameter of the
8642 MIME disposition information.
8643 </para>
8644 </listitem>
8645 <listitem>
8646 <para>
8647 <command>fld_disposition_creation_date</command> is
8648 the <command>creation-date</command> parameter of the
8649 MIME disposition information.
8650 </para>
8651 </listitem>
8652 <listitem>
8653 <para>
8654 <command>fld_disposition_modification_date</command> is
8655 the <command>modification-date</command> parameter of the
8656 MIME disposition information.
8657 </para>
8658 </listitem>
8659 <listitem>
8660 <para>
8661 <command>fld_disposition_read_date</command> is
8662 the <command>read-date</command> parameter of the
8663 MIME disposition information.
8664 </para>
8665 </listitem>
8666 <listitem>
8667 <para>
8668 <command>fld_disposition_size</command> is
8669 the <command>size</command> parameter of the
8670 MIME disposition information.
8671 </para>
8672 </listitem>
8673 <listitem>
8674 <para>
8675 <command>fld_language</command> is the language
8676 of the MIME part
8677 (see <xref linkend="mailmime-language">).
8678 </para>
8679 </listitem>
8680 <listitem>
8681 <para>
8682 <command>single_fields</command> is the structure to fill.
8683 </para>
8684 </listitem>
8685 <listitem>
8686 <para>
8687 <command>fld_fields</command> is the MIME fields list to
8688 use to fill the <command>single_fields</command>.
8689 </para>
8690 </listitem>
8691 </itemizedlist>
8692
8693 <para>
8694 <command>mailmime_single_fields_new()</command> creates and
8695 initializes a data structure with a
8696 value. Structures given as argument are referenced by the created
8697 object and will <emphasis>NOT</emphasis> be freed if the
8698 object is released.
8699 </para>
8700
8701 <para>
8702 <command>mailmime_single_fields_free()</command> frees
8703 memory used by the structure and
8704 substructures will <emphasis>NOT</emphasis> be
8705 released. They should be released by
8706 the application.
8707 </para>
8708
8709 <para>
8710 <command>mailimf_single_fields_init()</command> will
8711 initialize fill the data structure, using
8712 the given argument (<command>fld_fields</command> and
8713 <command>fld_content</command>). The interesting fields will
8714 be filled into single_fields.
8715 </para>
8716
8717 <example>
8718 <title>Creation and display of single fields</title>
8719
8720 <programlisting role="C">
8721#include &lt;libetpan/libetpan.h&gt;
8722
8723int main(int argc, char ** argv)
8724{
8725 struct mailmime_single_fields * single_fields;
8726 struct mailmime_fields * mime_fields;
8727 struct mailmime_content * content_type;
8728
8729 /* look at the example in mailmime_fields to see how to
8730 build a mailmime_fields */
8731 mime_fields = build_mime_fields();
8732
8733 /* look at the example in mailmime_content to see how to
8734 build a mailmime_content */
8735 content_type = build_mime_content();
8736
8737 single_fields = mailmime_single_fields_new(mime_fields, content_type);
8738
8739 /* do the things */
8740
8741 mailmime_single_fields_free(single_fields);
8742 mailmime_fields_free(mime_fields);
8743}
8744
8745void display_mime_single_fields(struct mailmime_single_fields * single_fields)
8746{
8747 if (single_fields-&gt;fld_content != NULL) {
8748 printf("content type:\n");
8749 display_mime_content(single_fields-&gt;fld_content);
8750 printf("\n");
8751 }
8752 if (single_fields-&gt;fld_content_charset != NULL) {
8753 printf("content type charset: %s\n",
8754 single_fields-&gt;fld_content_charset);
8755 printf("\n");
8756 }
8757 if (single_fields-&gt;fld_content_boundary != NULL) {
8758 printf("content type boundary: %s\n",
8759 single_fields-&gt;fld_content_boundary);
8760 printf("\n");
8761 }
8762 if (single_fields-&gt;content_name != NULL) {
8763 printf("content type name: %s\n", single_fields-&gt;content_name);
8764 printf("\n");
8765 }
8766 if (single_fields-&gt;fld_encoding != NULL) {
8767 printf("content transfer encoding:\n");
8768 display_mime_mechanism(single_fields-&gt;fld_encoding);
8769 printf("\n");
8770 }
8771 if (single_fields-&gt;fld_id != NULL) {
8772 printf("content id: %s\n", single_fields-&gt;fld_id);
8773 printf("\n");
8774 }
8775 if (single_fields-&gt;fld_description != NULL) {
8776 printf("content description: %s\n", single_fields-&gt;fld_description);
8777 printf("\n");
8778 }
8779 if (single_fields-&gt;fld_version != 0) {
8780 printf("mime version: %i.%i\n",
8781 single_fields-&gt;fld_version&gt;&gt; 16,
8782 single_fields-&gt;fld_version & 0xFFFF);
8783 printf("\n");
8784 }
8785 if (single_fields-&gt;fld_disposition != NULL) {
8786 printf("content disposition:\n");
8787 display_mime_disposition(single_fields-&gt;fld_disposition);
8788 printf("\n");
8789 }
8790 if (single_fields-&gt;fld_disposition_filename != NULL) {
8791 printf("content disposition filename: %s\n",
8792 single_fields-&gt;fld_disposition_filename);
8793 printf("\n");
8794 }
8795 if (single_fields-&gt;fld_disposition_creation_date != NULL) {
8796 printf("content disposition creation date: %s\n",
8797 single_fields-&gt;fld_disposition_creation_date);
8798 printf("\n");
8799 }
8800 if (single_fields-&gt;fld_disposition_modification_date != NULL) {
8801 printf("content disposition modification date: %s\n",
8802 single_fields-&gt;fld_disposition_modification_date);
8803 printf("\n");
8804 }
8805 if (single_fields-&gt;fld_disposition_read_date != NULL) {
8806 printf("content disposition read date: %s\n",
8807 single_fields-&gt;fld_disposition_read_date;
8808 printf("\n");
8809 }
8810 if (single_fields-&gt;fld_disposition_size != (size_t) -1) {
8811 printf("content disposition size : %i\n",
8812 single_fields-&gt;fld_disposition_size);
8813 printf("\n");
8814 }
8815 if (single_fields-&gt;language != NULL) {
8816 printf("content language:\n");
8817 display_mime_language(single_fields-&gt;fld_language);
8818 printf("\n");
8819 }
8820}
8821 </programlisting>
8822 </example>
8823 </sect2>
8824
8825 </sect1>
8826
8827 <!-- Parser functions -->
8828 <sect1>
8829 <title>Parser functions</title>
8830
8831 <!-- mailmime_content_parse -->
8832 <sect2 id="mailmime-content-parse">
8833 <title>mailmime_content_parse</title>
8834
8835 <programlisting role="C">
8836#include &lt;libetpan/libetpan.h&gt;
8837
8838int mailmime_content_parse(const char * message, size_t length,
8839 size_t * index,
8840 struct mailmime_content ** result);
8841 </programlisting>
8842
8843 <para>
8844 This function will parse the content of a
8845 <command>Content-Type</command> header field.
8846 </para>
8847
8848 <itemizedlist>
8849 <listitem>
8850 <para>
8851 <command>message</command> is a string containing
8852 the MIME content type.
8853 </para>
8854 </listitem>
8855 <listitem>
8856 <para>
8857 <command>length</command> is the size of the given
8858 string.
8859 </para>
8860 </listitem>
8861 <listitem>
8862 <para>
8863 <command>index</command> is a pointer to the start of
8864 the address in the given string, <command>(*
8865 index)</command> is modified to point at the end of the
8866 parsed data.
8867 </para>
8868 </listitem>
8869 <listitem>
8870 <para>
8871 <command>result</command>. The result of the parse
8872 operation is stored in <command>(* result)</command>
8873 (see <xref linkend="mailmime-content">).
8874 </para>
8875 </listitem>
8876 </itemizedlist>
8877
8878 <example>
8879 <title>Parsing MIME content type</title>
8880
8881 <programlisting role="C">
8882#include &lt;libetpan/libetpan.h&gt;
8883#include &lt;sys/stat.h&gt;
8884#include &lt;sys/mman.h&gt;
8885
8886int main(int argc, char ** argv)
8887{
8888 int fd;
8889 int r;
8890
8891 status = EXIT_FAILURE;
8892
8893 fd = open("message.rfc2822", O_RDONLY);
8894 if (fd &gt;= 0) {
8895 void * mem;
8896 struct stat stat_info;
8897
8898 r = fstat(fd, &amp;stat_info);
8899 if (r &gt;= 0) {
8900 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
8901 if (mem != MAP_FAILED) {
8902 struct mailimf_fields * f;
8903 size_t current_index;
8904
8905 current_index = 0;
8906 r = mailimf_fields_parse(mem, stat_info.st_size,
8907 &amp;current_index, &amp;f);
8908 if (r == MAILIMF_NO_ERROR) {
8909 clistiter * cur;
8910
8911 for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
8912 clist_next(cur)) {
8913 struct mailmime_field * mime_field;
8914 struct mailimf_field * field;
8915
8916 field = clist_content(cur);
8917
8918 if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
8919 if (strcasecmp(field-&gt;fld_data.fld_optional_field-&gt;fld_name,
8920 "Content-Type") == 0) {
8921 struct mailmime_content * content_type;
8922 size_t current_index;
8923
8924 current_index = 0;
8925 r = mailmime_content_parse(field-&gt;fld_data.fld_optional_field-&gt;fld_value,
8926 strlen(field-&gt;fld_data.fld_optional_field-&gt;fld_value),
8927 &amp;current_index, &amp;content_type);
8928 if (r == MAILIMF_NO_ERROR) {
8929 display_mime_content(content_type);
8930 /* do the things */
8931 status = EXIT_SUCCESS;
8932 mailmime_content_free(content_type);
8933 }
8934 }
8935 }
8936 }
8937 mailimf_fields_free(f);
8938 }
8939 }
8940 munmap(mem, stat_info.st_size);
8941 }
8942
8943 close(fd);
8944 }
8945
8946 exit(status);
8947}
8948 </programlisting>
8949 </example>
8950 </sect2>
8951
8952 <!-- mailmime_description_parse -->
8953 <sect2 id="mailmime-description-parse">
8954 <title>mailmime_description_parse</title>
8955
8956 <programlisting role="C">
8957#include &gt;libetpan/libetpan.h&lt;
8958
8959int mailmime_description_parse(const char * message, size_t length,
8960 size_t * index,
8961 char ** result);
8962 </programlisting>
8963
8964 <para>
8965 This will parse the content of
8966 <command>Content-Description</command> MIME header field.
8967 </para>
8968
8969 <itemizedlist>
8970 <listitem>
8971 <para>
8972 <command>message</command> is a string containing
8973 the MIME content description.
8974 </para>
8975 </listitem>
8976 <listitem>
8977 <para>
8978 <command>length</command> is the size of the given
8979 string.
8980 </para>
8981 </listitem>
8982 <listitem>
8983 <para>
8984 <command>index</command> is a pointer to the start of
8985 the address in the given string, <command>(*
8986 index)</command> is modified to point at the end of the
8987 parsed data.
8988 </para>
8989 </listitem>
8990 <listitem>
8991 <para>
8992 <command>result</command>. The result of the parse
8993 operation is stored in <command>(* result)</command>.
8994 The result string must be freed with
8995 <command>free()</command>.
8996 </para>
8997 </listitem>
8998 </itemizedlist>
8999
9000 <example>
9001 <title>Parsing MIME description</title>
9002
9003 <programlisting role="C">
9004#include &lt;libetpan/libetpan.h&gt;
9005#include &lt;sys/stat.h&gt;
9006#include &lt;sys/mman.h&gt;
9007
9008int main(int argc, char ** argv)
9009{
9010 int fd;
9011 int r;
9012
9013 status = EXIT_FAILURE;
9014
9015 fd = open("message.rfc2822", O_RDONLY);
9016 if (fd &gt;= 0) {
9017 void * mem;
9018 struct stat stat_info;
9019
9020 r = fstat(fd, &amp;stat_info);
9021 if (r &gt;= 0) {
9022 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
9023 if (mem != MAP_FAILED) {
9024 struct mailimf_fields * f;
9025 size_t current_index;
9026
9027 current_index = 0;
9028 r = mailimf_fields_parse(mem, stat_info.st_size,
9029 &amp;current_index, &amp;f);
9030 if (r == MAILIMF_NO_ERROR) {
9031 clistiter * cur;
9032
9033 for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
9034 clist_next(cur)) {
9035 struct mailmime_field * mime_field;
9036 struct mailimf_field * field;
9037
9038 field = clist_content(cur);
9039
9040 if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
9041 if (strcasecmp(field-&gt;fld_data.fld_optional_field-&gt;fld_name,
9042 "Content-Description") == 0) {
9043 char * description;
9044 size_t current_index;
9045
9046 current_index = 0;
9047 r = mailmime_description_parse(field-&gt;fld_data.fld_optional_field-&gt;fld_value,
9048 strlen(field-&gt;fld_data.fld_optional_field-&gt;fld_value),
9049 &amp;current_index, &amp;description);
9050 if (r == MAILIMF_NO_ERROR) {
9051 printf("%s\n", description);
9052 /* do the things */
9053 status = EXIT_SUCCESS;
9054 free(description);
9055 }
9056 }
9057 }
9058 }
9059 mailimf_fields_free(f);
9060 }
9061 }
9062 munmap(mem, stat_info.st_size);
9063 }
9064
9065 close(fd);
9066 }
9067
9068 exit(status);
9069}
9070 </programlisting>
9071 </example>
9072
9073
9074 </sect2>
9075
9076 <!-- mailmime_encoding_parse -->
9077 <sect2 id="mailmime-encoding-parse">
9078 <title>mailmime_encoding_parse</title>
9079
9080 <programlisting role="C">
9081#include &gt;libetpan/libetpan.h&lt;
9082
9083int mailmime_encoding_parse(const char * message, size_t length,
9084 size_t * index,
9085 struct mailmime_mechanism ** result);
9086 </programlisting>
9087
9088 <para>
9089 This function will parse the content of
9090 <command>Content-Transfer-Encoding</command> header field.
9091 </para>
9092
9093 <itemizedlist>
9094 <listitem>
9095 <para>
9096 <command>message</command> is a string containing
9097 the MIME encoding mechanism.
9098 </para>
9099 </listitem>
9100 <listitem>
9101 <para>
9102 <command>length</command> is the size of the given
9103 string.
9104 </para>
9105 </listitem>
9106 <listitem>
9107 <para>
9108 <command>index</command> is a pointer to the start of
9109 the address in the given string, <command>(*
9110 index)</command> is modified to point at the end of the
9111 parsed data.
9112 </para>
9113 </listitem>
9114 <listitem>
9115 <para>
9116 <command>result</command>. The result of the parse
9117 operation is stored in <command>(* result)</command>
9118 (see <xref linkend="mailmime-mechanism">).
9119 </para>
9120 </listitem>
9121 </itemizedlist>
9122
9123 <example>
9124 <title>parsing MIME encoding mechanism</title>
9125
9126 <programlisting role="C">
9127#include &lt;libetpan/libetpan.h&gt;
9128#include &lt;sys/stat.h&gt;
9129#include &lt;sys/mman.h&gt;
9130
9131int main(int argc, char ** argv)
9132{
9133 int fd;
9134 int r;
9135
9136 status = EXIT_FAILURE;
9137
9138 fd = open("message.rfc2822", O_RDONLY);
9139 if (fd &gt;= 0) {
9140 void * mem;
9141 struct stat stat_info;
9142
9143 r = fstat(fd, &amp;stat_info);
9144 if (r &gt;= 0) {
9145 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
9146 if (mem != MAP_FAILED) {
9147 struct mailimf_fields * f;
9148 size_t current_index;
9149
9150 current_index = 0;
9151 r = mailimf_fields_parse(mem, stat_info.st_size,
9152 &amp;current_index, &amp;f);
9153 if (r == MAILIMF_NO_ERROR) {
9154 clistiter * cur;
9155
9156 for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
9157 clist_next(cur)) {
9158 struct mailmime_field * mime_field;
9159 struct mailimf_field * field;
9160
9161 field = clist_content(cur);
9162
9163 if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
9164 if (strcasecmp(field-&gt;fld_data.fld_optional_field-&gt;fld_name,
9165 "Content-Transfer-Encoding") == 0) {
9166 struct mailmime_content * encoding;
9167 size_t current_index;
9168
9169 current_index = 0;
9170 r = mailmime_encoding_parse(field-&gt;fld_data.fld_optional_field-&gt;fld_value,
9171 strlen(field-&gt;fld_data.fld_optional_field-&gt;fld_value),
9172 &amp;current_index, &amp;encoding);
9173 if (r == MAILIMF_NO_ERROR) {
9174 display_mime_mechanism(encoding);
9175 /* do the things */
9176 status = EXIT_SUCCESS;
9177 mailmime_mechanism_free(encoding);
9178 }
9179 }
9180 }
9181 }
9182 mailimf_fields_free(f);
9183 }
9184 }
9185 munmap(mem, stat_info.st_size);
9186 }
9187
9188 close(fd);
9189 }
9190
9191 exit(status);
9192}
9193 </programlisting>
9194 </example>
9195 </sect2>
9196
9197 <!-- mailmime_field_parse -->
9198 <sect2 id="mailmime-field-parse">
9199 <title>mailmime_field_parse</title>
9200
9201 <programlisting role="C">
9202#include &lt;libetpan/libetpan.h&gt;
9203
9204int
9205mailmime_field_parse(struct mailimf_optional_field * field,
9206 struct mailmime_field ** result);
9207 </programlisting>
9208
9209 <para>
9210 This function will parse a MIME header field.
9211 </para>
9212
9213 <itemizedlist>
9214 <listitem>
9215 <para>
9216 <command>field</command> is a non-parsed field
9217 (see <xref linkend="mailimf-optional-field">).
9218 </para>
9219
9220 <para>
9221 <command>result</command>. The result of the parse
9222 operation is stored in <command>(* result)</command>
9223 (see <xref linkend="mailmime-field">).
9224 </para>
9225 </listitem>
9226 </itemizedlist>
9227
9228 <example>
9229 <title>parsing MIME header field</title>
9230
9231 <programlisting role="C">
9232#include &lt;libetpan/libetpan.h&gt;
9233#include &lt;sys/stat.h&gt;
9234#include &lt;sys/mman.h&gt;
9235
9236int main(int argc, char ** argv)
9237{
9238 int fd;
9239 int r;
9240
9241 status = EXIT_FAILURE;
9242
9243 fd = open("message.rfc2822", O_RDONLY);
9244 if (fd &gt;= 0) {
9245 void * mem;
9246 struct stat stat_info;
9247
9248 r = fstat(fd, &amp;stat_info);
9249 if (r &gt;= 0) {
9250 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
9251 if (mem != MAP_FAILED) {
9252 struct mailimf_fields * f;
9253 size_t current_index;
9254
9255 current_index = 0;
9256 r = mailimf_fields_parse(mem, stat_info.st_size,
9257 &amp;current_index, &amp;f);
9258 if (r == MAILIMF_NO_ERROR) {
9259 clistiter * cur;
9260
9261 for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
9262 clist_next(cur)) {
9263 struct mailmime_field * mime_field;
9264 struct mailimf_field * field;
9265
9266 field = clist_content(cur);
9267
9268 if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
9269 r = mailmime_field_parse(field-&gt;fld_data.fld_optional_field,
9270 &amp;mime_fields);
9271 if (r == MAILIMF_NO_ERROR) {
9272 display_mime_field(mime_field);
9273 mailmime_field_free(mime_field);
9274 status = EXIT_SUCCESS;
9275 }
9276 }
9277 }
9278
9279 mailimf_fields_free(f);
9280 }
9281 }
9282 munmap(mem, stat_info.st_size);
9283 }
9284
9285 close(fd);
9286 }
9287
9288 exit(status);
9289}
9290 </programlisting>
9291 </example>
9292
9293 </sect2>
9294
9295 <!-- mailmime_id_parse -->
9296 <sect2 id="mailmime-id-parse">
9297 <title>mailmime_id_parse</title>
9298
9299 <programlisting role="C">
9300#include &gt;libetpan/libetpan.h&lt;
9301
9302int mailmime_id_parse(const char * message, size_t length,
9303 size_t * index, char ** result);
9304 </programlisting>
9305
9306 <para>
9307 This will parse the content of
9308 <command>Content-ID</command> MIME header field.
9309 </para>
9310
9311 <itemizedlist>
9312 <listitem>
9313 <para>
9314 <command>message</command> is a string containing
9315 the MIME content identifier.
9316 </para>
9317 </listitem>
9318 <listitem>
9319 <para>
9320 <command>length</command> is the size of the given
9321 string.
9322 </para>
9323 </listitem>
9324 <listitem>
9325 <para>
9326 <command>index</command> is a pointer to the start of
9327 the address in the given string, <command>(*
9328 index)</command> is modified to point at the end of the
9329 parsed data.
9330 </para>
9331 </listitem>
9332 <listitem>
9333 <para>
9334 <command>result</command>. The result of the parse
9335 operation is stored in <command>(* result)</command>.
9336 The result string must be freed with
9337 <command>free()</command>.
9338 </para>
9339 </listitem>
9340 </itemizedlist>
9341
9342 <example>
9343 <title>Parsing MIME content identifier</title>
9344
9345 <programlisting role="C">
9346#include &lt;libetpan/libetpan.h&gt;
9347#include &lt;sys/stat.h&gt;
9348#include &lt;sys/mman.h&gt;
9349
9350int main(int argc, char ** argv)
9351{
9352 int fd;
9353 int r;
9354
9355 status = EXIT_FAILURE;
9356
9357 fd = open("message.rfc2822", O_RDONLY);
9358 if (fd &gt;= 0) {
9359 void * mem;
9360 struct stat stat_info;
9361
9362 r = fstat(fd, &amp;stat_info);
9363 if (r &gt;= 0) {
9364 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
9365 if (mem != MAP_FAILED) {
9366 struct mailimf_fields * f;
9367 size_t current_index;
9368
9369 current_index = 0;
9370 r = mailimf_fields_parse(mem, stat_info.st_size,
9371 &amp;current_index, &amp;f);
9372 if (r == MAILIMF_NO_ERROR) {
9373 clistiter * cur;
9374
9375 for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
9376 clist_next(cur)) {
9377 struct mailmime_field * mime_field;
9378 struct mailimf_field * field;
9379
9380 field = clist_content(cur);
9381
9382 if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
9383 if (strcasecmp(field-&gt;fld_data.fld_optional_field-&gt;fld_name,
9384 "Content-ID") == 0) {
9385 char * id;
9386 size_t current_index;
9387
9388 current_index = 0;
9389 r = mailmime_id_parse(field-&gt;fld_data.fld_optional_field-&gt;fld_value,
9390 strlen(field-&gt;fld_data.fld_optional_field-&gt;fld_value),
9391 &amp;current_index, &amp;id);
9392 if (r == MAILIMF_NO_ERROR) {
9393 printf("%s\n", id);
9394 /* do the things */
9395 status = EXIT_SUCCESS;
9396 free(id);
9397 }
9398 }
9399 }
9400 }
9401 mailimf_fields_free(f);
9402 }
9403 }
9404 munmap(mem, stat_info.st_size);
9405 }
9406
9407 close(fd);
9408 }
9409
9410 exit(status);
9411}
9412 </programlisting>
9413 </example>
9414 </sect2>
9415
9416 <!-- mailmime_fields_parse -->
9417 <sect2 id="mailmime-fields-parse">
9418 <title>mailmime_fields_parse</title>
9419
9420 <programlisting role="C">
9421#include &lt;libetpan/libetpan.h&gt;
9422
9423int
9424mailmime_fields_parse(struct mailimf_fields * fields,
9425 struct mailmime_fields ** result);
9426 </programlisting>
9427
9428 <para>
9429 This function will parse a MIME header fields.
9430 </para>
9431
9432 <itemizedlist>
9433 <listitem>
9434 <para>
9435 <command>fields</command> is a list of RFC 2822 fields
9436 (see <xref linkend="mailimf-fields">).
9437 </para>
9438
9439 <para>
9440 <command>result</command>. The result of the parse
9441 operation is stored in <command>(* result)</command>
9442 (see <xref linkend="mailmime-fields">).
9443 </para>
9444 </listitem>
9445 </itemizedlist>
9446
9447 <example>
9448 <title>parsing MIME header fields</title>
9449
9450 <programlisting role="C">
9451#include &lt;libetpan/libetpan.h&gt;
9452#include &lt;sys/stat.h&gt;
9453#include &lt;sys/mman.h&gt;
9454
9455int main(int argc, char ** argv)
9456{
9457 int fd;
9458 int r;
9459
9460 status = EXIT_FAILURE;
9461
9462 fd = open("message.rfc2822", O_RDONLY);
9463 if (fd &gt;= 0) {
9464 void * mem;
9465 struct stat stat_info;
9466
9467 r = fstat(fd, &amp;stat_info);
9468 if (r &gt;= 0) {
9469 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
9470 if (mem != MAP_FAILED) {
9471 struct mailimf_fields * f;
9472 size_t current_index;
9473
9474 current_index = 0;
9475 r = mailimf_fields_parse(mem, stat_info.st_size,
9476 &amp;current_index, &amp;f);
9477 if (r == MAILIMF_NO_ERROR) {
9478 struct mailmime_fields * mime_fields;
9479
9480 r = mailmime_fields_parse(f, &amp;mime_fields);
9481 if (r == MAILIMF_NO_ERROR) {
9482 display_mime_fields(mime_fields);
9483 mailmime_fields_free(mime_fields);
9484 status = EXIT_SUCCESS;
9485 }
9486
9487 mailimf_fields_free(f);
9488 }
9489 }
9490 munmap(mem, stat_info.st_size);
9491 }
9492
9493 close(fd);
9494 }
9495
9496 exit(status);
9497}
9498 </programlisting>
9499 </example>
9500
9501 </sect2>
9502
9503 <!-- mailmime_version_parse -->
9504 <sect2 id="mailmime-version-parse">
9505 <title>mailmime_version_parse</title>
9506
9507 <programlisting role="C">
9508#include &lt;libetpan/libetpan.h&gt;
9509
9510int mailmime_version_parse(const char * message, size_t length,
9511 size_t * index,
9512 uint32_t * result);
9513 </programlisting>
9514
9515 <para>
9516 This will parse the content of
9517 <command>MIME-Version</command> MIME header field.
9518 </para>
9519
9520 <itemizedlist>
9521 <listitem>
9522 <para>
9523 <command>message</command> is a string containing
9524 the MIME version.
9525 </para>
9526 </listitem>
9527 <listitem>
9528 <para>
9529 <command>length</command> is the size of the given
9530 string.
9531 </para>
9532 </listitem>
9533 <listitem>
9534 <para>
9535 <command>index</command> is a pointer to the start of
9536 the address in the given string, <command>(*
9537 index)</command> is modified to point at the end of the
9538 parsed data.
9539 </para>
9540 </listitem>
9541 <listitem>
9542 <para>
9543 <command>result</command>. The result of the parse
9544 operation is stored in <command>(* result)</command>
9545 (see <xref linkend="mailmime-field">).
9546 </para>
9547 </listitem>
9548 </itemizedlist>
9549
9550 <example>
9551 <title>parsing MIME version</title>
9552
9553 <programlisting role="C">
9554#include &lt;libetpan/libetpan.h&gt;
9555#include &lt;sys/stat.h&gt;
9556#include &lt;sys/mman.h&gt;
9557
9558int main(int argc, char ** argv)
9559{
9560 int fd;
9561 int r;
9562
9563 status = EXIT_FAILURE;
9564
9565 fd = open("message.rfc2822", O_RDONLY);
9566 if (fd &gt;= 0) {
9567 void * mem;
9568 struct stat stat_info;
9569
9570 r = fstat(fd, &amp;stat_info);
9571 if (r &gt;= 0) {
9572 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
9573 if (mem != MAP_FAILED) {
9574 struct mailimf_fields * f;
9575 size_t current_index;
9576
9577 current_index = 0;
9578 r = mailimf_fields_parse(mem, stat_info.st_size,
9579 &amp;current_index, &amp;f);
9580 if (r == MAILIMF_NO_ERROR) {
9581 clistiter * cur;
9582
9583 for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
9584 clist_next(cur)) {
9585 struct mailmime_field * mime_field;
9586 struct mailimf_field * field;
9587
9588 field = clist_content(cur);
9589
9590 if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
9591 if (strcasecmp(field-&gt;fld_data.fld_optional_field-&gt;fld_name,
9592 "MIME-Version") == 0) {
9593 uint32_t version;
9594 size_t current_index;
9595
9596 current_index = 0;
9597 r = mailmime_version_parse(field-&gt;fld_data.fld_optional_field-&gt;fld_value,
9598 strlen(field-&gt;fld_data.fld_optional_field-&gt;fld_value),
9599 &amp;current_index, &amp;version);
9600 if (r == MAILIMF_NO_ERROR) {
9601 printf("%i.%i\n", version &gt;&gt; 16, version &amp; 0xFFFF);
9602 /* do the things */
9603 status = EXIT_SUCCESS;
9604 free(description);
9605 }
9606 }
9607 }
9608 }
9609 mailimf_fields_free(f);
9610 }
9611 }
9612 munmap(mem, stat_info.st_size);
9613 }
9614
9615 close(fd);
9616 }
9617
9618 exit(status);
9619}
9620 </programlisting>
9621 </example>
9622 </sect2>
9623
9624 <!-- mailmime_parameter_parse -->
9625 <sect2 id="mailmime-parameter-parse">
9626 <title>mailmime_parameter_parse</title>
9627
9628 <programlisting role="C">
9629#include &lt;libetpan/libetpan.h&gt;
9630
9631int mailmime_parameter_parse(const char * message, size_t length,
9632 size_t * index,
9633 struct mailmime_parameter ** result);
9634 </programlisting>
9635
9636 <para>
9637 This will parse a MIME parameter (parameter of
9638 <command>Content-Type</command> or parameter of
9639 <command>Content-Disposition</command>).
9640 </para>
9641
9642 <itemizedlist>
9643 <listitem>
9644 <para>
9645 <command>message</command> is a string containing
9646 the MIME parameter.
9647 </para>
9648 </listitem>
9649 <listitem>
9650 <para>
9651 <command>length</command> is the size of the given
9652 string.
9653 </para>
9654 </listitem>
9655 <listitem>
9656 <para>
9657 <command>index</command> is a pointer to the start of
9658 the address in the given string, <command>(*
9659 index)</command> is modified to point at the end of the
9660 parsed data.
9661 </para>
9662 </listitem>
9663 <listitem>
9664 <para>
9665 <command>result</command>. The result of the parse
9666 operation is stored in <command>(* result)</command>
9667 (see <xref linkend="mailmime-parameter">).
9668 </para>
9669 </listitem>
9670 </itemizedlist>
9671
9672 <example>
9673 <title>parsing a MIME parameter</title>
9674
9675 <programlisting role="C">
9676#include &lt;libetpan/libetpan.h&gt;
9677
9678#define PARAM_STR "foo=bar"
9679
9680int main(int argc, char ** argv)
9681{
9682 int fd;
9683 int r;
9684 size_t current_index;
9685 struct mailmime_parameter * param;
9686 int status;
9687
9688 status = EXIT_FAILURE;
9689
9690 current_index = 0;
9691 r = mailmime_parameter_parse(PARAM_STR, sizeof(PARAM_STR) - 1,
9692 &amp;current_index, &amp;param);
9693 if (r == MAILIMF_NO_ERROR) {
9694 display_mime_parameter(param);
9695 /* do the things */
9696 mailmime_parameter_free(param);
9697 status = EXIT_SUCCESS;
9698 }
9699
9700 exit(status);
9701}
9702 </programlisting>
9703 </example>
9704 </sect2>
9705
9706 <!-- mailmime_language_parse -->
9707 <sect2 id="mailmime-language-parse">
9708 <title>mailmime_language_parse</title>
9709
9710 <programlisting role="C">
9711#include &lt;libetpan/libetpan.h&gt;
9712
9713int mailmime_language_parse(const char * message, size_t length,
9714 size_t * index,
9715 struct mailmime_language ** result);
9716 </programlisting>
9717
9718 <para>
9719 This function will parse the content of a
9720 <command>Content-Language</command> header.
9721 </para>
9722
9723 <itemizedlist>
9724 <listitem>
9725 <para>
9726 <command>message</command> is a string containing
9727 the MIME content language.
9728 </para>
9729 </listitem>
9730 <listitem>
9731 <para>
9732 <command>length</command> is the size of the given
9733 string.
9734 </para>
9735 </listitem>
9736 <listitem>
9737 <para>
9738 <command>index</command> is a pointer to the start of
9739 the address in the given string, <command>(*
9740 index)</command> is modified to point at the end of the
9741 parsed data.
9742 </para>
9743 </listitem>
9744 <listitem>
9745 <para>
9746 <command>result</command>. The result of the parse
9747 operation is stored in <command>(* result)</command>
9748 (see <xref linkend="mailmime-language">).
9749 </para>
9750 </listitem>
9751 </itemizedlist>
9752
9753 <example>
9754 <title>Parsing the MIME content langage</title>
9755
9756 <programlisting role="C">
9757#include &lt;libetpan/libetpan.h&gt;
9758#include &lt;sys/stat.h&gt;
9759#include &lt;sys/mman.h&gt;
9760
9761int main(int argc, char ** argv)
9762{
9763 int fd;
9764 int r;
9765
9766 status = EXIT_FAILURE;
9767
9768 fd = open("message.rfc2822", O_RDONLY);
9769 if (fd &gt;= 0) {
9770 void * mem;
9771 struct stat stat_info;
9772
9773 r = fstat(fd, &amp;stat_info);
9774 if (r &gt;= 0) {
9775 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
9776 if (mem != MAP_FAILED) {
9777 struct mailimf_fields * f;
9778 size_t current_index;
9779
9780 current_index = 0;
9781 r = mailimf_fields_parse(mem, stat_info.st_size,
9782 &amp;current_index, &amp;f);
9783 if (r == MAILIMF_NO_ERROR) {
9784 clistiter * cur;
9785
9786 for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
9787 clist_next(cur)) {
9788 struct mailmime_field * mime_field;
9789 struct mailimf_field * field;
9790
9791 field = clist_content(cur);
9792
9793 if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
9794 if (strcasecmp(field-&gt;fld_data.fld_optional_field-&gt;fld_name,
9795 "Content-Language") == 0) {
9796 struct mailmime_language * lang;
9797 size_t current_index;
9798
9799 current_index = 0;
9800 r = mailmime_id_parse(field-&gt;fld_data.fld_optional_field-&gt;fld_value,
9801 strlen(field-&gt;fld_data.fld_optional_field-&gt;fld_value),
9802 &amp;current_index, &amp;lang);
9803 if (r == MAILIMF_NO_ERROR) {
9804 display_mime_language(lang);
9805 /* do the things */
9806 status = EXIT_SUCCESS;
9807 free(id);
9808 }
9809 }
9810 }
9811 }
9812 mailimf_fields_free(f);
9813 }
9814 }
9815 munmap(mem, stat_info.st_size);
9816 }
9817
9818 close(fd);
9819 }
9820
9821 exit(status);
9822}
9823 </programlisting>
9824 </example>
9825 </sect2>
9826
9827 <!-- mailmime_disposition_parse -->
9828 <sect2 id="mailmime-disposition-parse">
9829 <title>mailmime_disposition_parse</title>
9830
9831 <programlisting role="C">
9832#include &lt;libetpan/libetpan.h&gt;
9833
9834int mailmime_disposition_parse(const char * message, size_t length,
9835 size_t * index,
9836 struct mailmime_disposition ** result);
9837 </programlisting>
9838
9839 <para>
9840 This function will parse the content of a
9841 <command>Content-Disposition</command> MIME header field.
9842 </para>
9843
9844 <itemizedlist>
9845 <listitem>
9846 <para>
9847 <command>message</command> is a string containing
9848 the MIME content disposition.
9849 </para>
9850 </listitem>
9851 <listitem>
9852 <para>
9853 <command>length</command> is the size of the given
9854 string.
9855 </para>
9856 </listitem>
9857 <listitem>
9858 <para>
9859 <command>index</command> is a pointer to the start of
9860 the address in the given string, <command>(*
9861 index)</command> is modified to point at the end of the
9862 parsed data.
9863 </para>
9864 </listitem>
9865 <listitem>
9866 <para>
9867 <command>result</command>. The result of the parse
9868 operation is stored in <command>(* result)</command>
9869 (see <xref linkend="mailmime-disposition">).
9870 </para>
9871 </listitem>
9872 </itemizedlist>
9873
9874 <example>
9875 <title>Parsing the MIME content disposition</title>
9876
9877 <programlisting role="C">
9878#include &lt;libetpan/libetpan.h&gt;
9879#include &lt;sys/stat.h&gt;
9880#include &lt;sys/mman.h&gt;
9881
9882int main(int argc, char ** argv)
9883{
9884 int fd;
9885 int r;
9886
9887 status = EXIT_FAILURE;
9888
9889 fd = open("message.rfc2822", O_RDONLY);
9890 if (fd &gt;= 0) {
9891 void * mem;
9892 struct stat stat_info;
9893
9894 r = fstat(fd, &amp;stat_info);
9895 if (r &gt;= 0) {
9896 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
9897 if (mem != MAP_FAILED) {
9898 struct mailimf_fields * f;
9899 size_t current_index;
9900
9901 current_index = 0;
9902 r = mailimf_fields_parse(mem, stat_info.st_size,
9903 &amp;current_index, &amp;f);
9904 if (r == MAILIMF_NO_ERROR) {
9905 clistiter * cur;
9906
9907 for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
9908 clist_next(cur)) {
9909 struct mailmime_field * mime_field;
9910 struct mailimf_field * field;
9911
9912 field = clist_content(cur);
9913
9914 if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
9915 if (strcasecmp(field-&gt;fld_data.fld_optional_field-&gt;fld_name,
9916 "Content-Disposition") == 0) {
9917 struct mailmime_disposition * dsp;
9918 size_t current_index;
9919
9920 current_index = 0;
9921 r = mailmime_id_parse(field-&gt;fld_data.fld_optional_field-&gt;fld_value,
9922 strlen(field-&gt;fld_data.fld_optional_field-&gt;fld_value),
9923 &amp;current_index, &amp;dsp);
9924 if (r == MAILIMF_NO_ERROR) {
9925 display_mime_disposition(dsp);
9926 /* do the things */
9927 status = EXIT_SUCCESS;
9928 free(id);
9929 }
9930 }
9931 }
9932 }
9933 mailimf_fields_free(f);
9934 }
9935 }
9936 munmap(mem, stat_info.st_size);
9937 }
9938
9939 close(fd);
9940 }
9941
9942 exit(status);
9943}
9944 </programlisting>
9945 </example>
9946 </sect2>
9947
9948 <!-- mailmime_disposition_type_parse -->
9949 <sect2 id="mailmime-disposition-type-parse">
9950 <title>mailmime_disposition_type_parse</title>
9951
9952 <programlisting role="C">
9953#include &lt;libetpan/libetpan.h&gt;
9954
9955int
9956mailmime_disposition_type_parse(const char * message, size_t length,
9957 size_t * index,
9958 struct mailmime_disposition_type **
9959 result);
9960 </programlisting>
9961
9962 <para>
9963 This function will parse the type of MIME content
9964 disposition.
9965 </para>
9966
9967 <itemizedlist>
9968 <listitem>
9969 <para>
9970 <command>message</command> is a string containing
9971 the MIME content disposition type.
9972 </para>
9973 </listitem>
9974 <listitem>
9975 <para>
9976 <command>length</command> is the size of the given
9977 string.
9978 </para>
9979 </listitem>
9980 <listitem>
9981 <para>
9982 <command>index</command> is a pointer to the start of
9983 the address in the given string, <command>(*
9984 index)</command> is modified to point at the end of the
9985 parsed data.
9986 </para>
9987 </listitem>
9988 <listitem>
9989 <para>
9990 <command>result</command>. The result of the parse
9991 operation is stored in <command>(* result)</command>
9992 (see <xref linkend="mailmime-disposition-type">).
9993 </para>
9994 </listitem>
9995 </itemizedlist>
9996
9997 <example>
9998 <title>parsing a MIME content disposition type</title>
9999
10000 <programlisting role="C">
10001#include &lt;libetpan/libetpan.h&gt;
10002
10003#define DSP_TYPE_STR "attachment"
10004
10005int main(int argc, char ** argv)
10006{
10007 int fd;
10008 int r;
10009 size_t current_index;
10010 struct mailmime_disposition_type * dsp_type;
10011 int status;
10012
10013 status = EXIT_FAILURE;
10014
10015 current_index = 0;
10016 r = mailmime_disposition_type_parse(DSP_TYPE_STR, sizeof(DSP_TYPE_STR) - 1,
10017 &amp;current_index, &amp;dsp_type);
10018 if (r == MAILIMF_NO_ERROR) {
10019 display_mime_disposition_type(dsp_type);
10020 /* do the things */
10021 mailmime_disposition_type_free(dsp_type);
10022 status = EXIT_SUCCESS;
10023 }
10024
10025 exit(status);
10026}
10027 </programlisting>
10028 </example>
10029 </sect2>
10030
10031 <!-- mailmime_encoded_phrase_parse -->
10032 <sect2 id="mailmime-encoded-phrase-parse">
10033 <title>mailmime_encoded_phrase_parse</title>
10034
10035 <programlisting role="C">
10036#include &lt;libetpan/libetpan.h&gt;
10037
10038int mailmime_encoded_phrase_parse(const char * default_fromcode,
10039 const char * message, size_t length,
10040 size_t * index, const char * tocode,
10041 char ** result);
10042 </programlisting>
10043
10044 <para>
10045 This function will decode a MIME encoded header string,
10046 encoded with RFC 2047.
10047 </para>
10048
10049 <itemizedlist>
10050 <listitem>
10051 <para>
10052 <command>default_fromcode</command> is the default
10053 code to use for parts of string that are not marked
10054 with charset.
10055 </para>
10056 </listitem>
10057 <listitem>
10058 <para>
10059 <command>message</command> is the string to decode.
10060 </para>
10061 </listitem>
10062 <listitem>
10063 <para>
10064 <command>length</command> is the size of the given
10065 string.
10066 </para>
10067 </listitem>
10068 <listitem>
10069 <para>
10070 <command>index</command> is a pointer to the start of
10071 the address in the given string, <command>(*
10072 index)</command> is modified to point at the end of the
10073 parsed data.
10074 </para>
10075 </listitem>
10076 <listitem>
10077 <para>
10078 <command>tocode</command> is the destination charset
10079 for decoding.
10080 </para>
10081 </listitem>
10082 <listitem>
10083 <para>
10084 <command>result</command>. The result of the parse
10085 operation is stored in <command>(* result)</command>.
10086 </para>
10087 </listitem>
10088 </itemizedlist>
10089
10090 <example>
10091 <title>decoding a MIME encoded header string</title>
10092
10093 <programlisting role="C">
10094#include &lt;libetpan/libetpan.h&gt;
10095
10096#define TEST_STRING "=?iso-8859-1?ab?= =?iso-8859-15?cd?="
10097
10098int main(int argc, char ** argv)
10099{
10100 size_t cur_token;
10101 char * decoded_subject;
10102
10103 cur_token = 0;
10104 mailmime_encoded_phrase_parse("iso-8859-1",
10105 TEST_STRING, sizeof(TEST_STRING),
10106 &amp;cur_token, "iso-8859-1", &amp;decoded_subject);
10107
10108 printf("%s\n", decoded_subject);
10109
10110 /* do the things */
10111
10112 free(decoded_subject);
10113}
10114 </programlisting>
10115 </example>
10116
10117 </sect2>
10118
10119 <!-- mailmime_parse -->
10120 <sect2 id="mailmime-parse">
10121 <title>mailmime_parse</title>
10122
10123 <programlisting role="C">
10124#include &lt;libetpan/libetpan.h&gt;
10125
10126int mailmime_parse(const char * message, size_t length,
10127 size_t * index, struct mailmime ** result);
10128 </programlisting>
10129
10130 <para>
10131 This will parse a MIME message.
10132 </para>
10133
10134 <itemizedlist>
10135 <listitem>
10136 <para>
10137 <command>message</command> is a string containing
10138 the MIME message.
10139 </para>
10140 </listitem>
10141 <listitem>
10142 <para>
10143 <command>length</command> is the size of the given
10144 string.
10145 </para>
10146 </listitem>
10147 <listitem>
10148 <para>
10149 <command>index</command> is a pointer to the start of
10150 the address in the given string, <command>(*
10151 index)</command> is modified to point at the end of the
10152 parsed data.
10153 </para>
10154 </listitem>
10155 <listitem>
10156 <para>
10157 <command>result</command>. The result of the parse
10158 operation is stored in <command>(* result)</command>
10159 (see <xref linkend="mailmime">).
10160 </para>
10161 </listitem>
10162 </itemizedlist>
10163
10164 <example>
10165 <title>parsing a MIME message</title>
10166
10167 <programlisting role="C">
10168#include &lt;libetpan/libetpan.h&gt;
10169#include &lt;sys/stat.h&gt;
10170#include &lt;sys/mman.h&gt;
10171
10172int main(int argc, char ** argv)
10173{
10174 int fd;
10175 int r;
10176
10177 status = EXIT_FAILURE;
10178
10179 fd = open("message.rfc2822", O_RDONLY);
10180 if (fd &gt;= 0) {
10181 void * mem;
10182 struct stat stat_info;
10183
10184 r = fstat(fd, &amp;stat_info);
10185 if (r &gt;= 0) {
10186 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
10187 if (mem != MAP_FAILED) {
10188 struct mailmime * mime;
10189 size_t current_index;
10190
10191 current_index = 0;
10192 r = mailmime_parse(mem, stat_info.st_size,
10193 &amp;current_index, &amp;mime);
10194 if (r == MAILIMF_NO_ERROR) {
10195 display_mime(mime);
10196 /* do the things */
10197 status = EXIT_SUCCESS;
10198 mailmime_free(mime);
10199 }
10200 }
10201 munmap(mem, stat_info.st_size);
10202 }
10203
10204 close(fd);
10205 }
10206
10207 exit(status);
10208}
10209 </programlisting>
10210 </example>
10211 </sect2>
10212
10213 <!-- mailmime_base64_body_parse -->
10214 <sect2 id="mailmime-base64-body-parse">
10215 <title>mailmime_base64_body_parse</title>
10216
10217 <programlisting role="C">
10218#include &lt;libetpan/libetpan.h&gt;
10219
10220int mailmime_base64_body_parse(const char * message, size_t length,
10221 size_t * index, char ** result,
10222 size_t * result_len);
10223 </programlisting>
10224
10225 <para>
10226 This function will parse a body part encoded using base64.
10227 </para>
10228
10229 <itemizedlist>
10230 <listitem>
10231 <para>
10232 <command>message</command> is a string encoded using
10233 base64.
10234 </para>
10235 </listitem>
10236 <listitem>
10237 <para>
10238 <command>length</command> is the size of the given
10239 string.
10240 </para>
10241 </listitem>
10242 <listitem>
10243 <para>
10244 <command>index</command> is a pointer to the start of
10245 the address in the given string, <command>(*
10246 index)</command> is modified to point at the end of the
10247 parsed data.
10248 </para>
10249 </listitem>
10250 <listitem>
10251 <para>
10252 <command>result</command>. The result of the parse
10253 operation is stored in <command>(* result)</command>
10254 The result must be freed with
10255 <command>mmap_string_unref()</command>.
10256 </para>
10257 </listitem>
10258 </itemizedlist>
10259
10260 <example>
10261 <title>Parsing a base64 encoded part</title>
10262
10263 <programlisting role="C">
10264#include &lt;libetpan/libetpan.h&gt;
10265#include &lt;sys/stat.h&gt;
10266#include &lt;sys/mman.h&gt;
10267
10268int main(int argc, char ** argv)
10269{
10270 int fd;
10271 int r;
10272
10273 status = EXIT_FAILURE;
10274
10275 fd = open("message.rfc2822", O_RDONLY);
10276 if (fd &gt;= 0) {
10277 void * mem;
10278 struct stat stat_info;
10279
10280 r = fstat(fd, &amp;stat_info);
10281 if (r &gt;= 0) {
10282 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
10283 if (mem != MAP_FAILED) {
10284 struct mailimf_fields * f;
10285 size_t current_index;
10286 char * result;
10287 size_t result_len;
10288
10289 current_index = 0;
10290 r = mailmime_base64_body_parse(mem, stat_info.st_size,
10291 &amp;current_index, &amp;result, &amp;result_len);
10292 if (r == MAILIMF_NO_ERROR) {
10293
10294 /* do the things */
10295
10296 mailmime_decoded_part_free(mem);
10297 status = EXIT_SUCCESS;
10298 }
10299 }
10300 munmap(mem, stat_info.st_size);
10301 }
10302
10303 close(fd);
10304 }
10305
10306 exit(status);
10307}
10308 </programlisting>
10309 </example>
10310 </sect2>
10311
10312 <!-- mailmime_quoted_printable_body_parse -->
10313 <sect2 id="mailmime-quoted-printable-body-parse">
10314 <title>mailmime_quoted_printable_body_parse</title>
10315
10316 <programlisting role="C">
10317#include &lt;libetpan/libetpan.h&gt;
10318
10319int mailmime_quoted_printable_body_parse(const char * message, size_t length,
10320 size_t * index, char ** result,
10321 size_t * result_len, int in_header);
10322 </programlisting>
10323
10324 <para>
10325 This function will parse a body part encoded using quoted
10326 printable.
10327 </para>
10328
10329 <itemizedlist>
10330 <listitem>
10331 <para>
10332 <command>message</command> is a string encoded using
10333 quoted printable.
10334 </para>
10335 </listitem>
10336 <listitem>
10337 <para>
10338 <command>length</command> is the size of the given
10339 string.
10340 </para>
10341 </listitem>
10342 <listitem>
10343 <para>
10344 <command>index</command> is a pointer to the start of
10345 the address in the given string, <command>(*
10346 index)</command> is modified to point at the end of the
10347 parsed data.
10348 </para>
10349 </listitem>
10350 <listitem>
10351 <para>
10352 <command>result</command>. The result of the parse
10353 operation is stored in <command>(* result)</command>
10354 The result must be freed with
10355 <command>mmap_string_unref()</command>.
10356 </para>
10357 </listitem>
10358 </itemizedlist>
10359
10360 <example>
10361 <title>Parsing a quoted printable encoded part</title>
10362
10363 <programlisting role="C">
10364#include &lt;libetpan/libetpan.h&gt;
10365#include &lt;sys/stat.h&gt;
10366#include &lt;sys/mman.h&gt;
10367
10368int main(int argc, char ** argv)
10369{
10370 int fd;
10371 int r;
10372
10373 status = EXIT_FAILURE;
10374
10375 fd = open("message.rfc2822", O_RDONLY);
10376 if (fd &gt;= 0) {
10377 void * mem;
10378 struct stat stat_info;
10379
10380 r = fstat(fd, &amp;stat_info);
10381 if (r &gt;= 0) {
10382 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
10383 if (mem != MAP_FAILED) {
10384 struct mailimf_fields * f;
10385 size_t current_index;
10386 char * result;
10387 size_t result_len;
10388
10389 current_index = 0;
10390 r = mailmime_quoted_printable_body_parse(mem, stat_info.st_size,
10391 &amp;current_index, &amp;result, &amp;result_len);
10392 if (r == MAILIMF_NO_ERROR) {
10393
10394 /* do the things */
10395
10396 mailmime_decoded_part_free(mem);
10397 status = EXIT_SUCCESS;
10398 }
10399 }
10400 munmap(mem, stat_info.st_size);
10401 }
10402
10403 close(fd);
10404 }
10405
10406 exit(status);
10407}
10408 </programlisting>
10409 </example>
10410 </sect2>
10411
10412 <!-- mailmime_binary_body_parse -->
10413 <sect2 id="mailmime-binary-body-parse">
10414 <title>mailmime_binary_body_parse</title>
10415
10416 <programlisting role="C">
10417#include &lt;libetpan/libetpan.h&gt;
10418
10419int mailmime_binary_body_parse(const char * message, size_t length,
10420 size_t * index, char ** result,
10421 size_t * result_len);
10422 </programlisting>
10423
10424 <para>
10425 This function will parse a body part encoded using binary
10426 (no encoding).
10427 </para>
10428
10429 <itemizedlist>
10430 <listitem>
10431 <para>
10432 <command>message</command> is a string encoded using
10433 binary.
10434 </para>
10435 </listitem>
10436 <listitem>
10437 <para>
10438 <command>length</command> is the size of the given
10439 string.
10440 </para>
10441 </listitem>
10442 <listitem>
10443 <para>
10444 <command>index</command> is a pointer to the start of
10445 the address in the given string, <command>(*
10446 index)</command> is modified to point at the end of the
10447 parsed data.
10448 </para>
10449 </listitem>
10450 <listitem>
10451 <para>
10452 <command>result</command>. The result of the parse
10453 operation is stored in <command>(* result)</command>
10454 The result must be freed with
10455 <command>mmap_string_unref()</command>.
10456 </para>
10457 </listitem>
10458 </itemizedlist>
10459
10460 <example>
10461 <title>Parsing a binary encoded part</title>
10462
10463 <programlisting role="C">
10464#include &lt;libetpan/libetpan.h&gt;
10465#include &lt;sys/stat.h&gt;
10466#include &lt;sys/mman.h&gt;
10467
10468int main(int argc, char ** argv)
10469{
10470 int fd;
10471 int r;
10472
10473 status = EXIT_FAILURE;
10474
10475 fd = open("message.rfc2822", O_RDONLY);
10476 if (fd &gt;= 0) {
10477 void * mem;
10478 struct stat stat_info;
10479
10480 r = fstat(fd, &amp;stat_info);
10481 if (r &gt;= 0) {
10482 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
10483 if (mem != MAP_FAILED) {
10484 struct mailimf_fields * f;
10485 size_t current_index;
10486 char * result;
10487 size_t result_len;
10488
10489 current_index = 0;
10490 r = mailmime_binary_body_parse(mem, stat_info.st_size,
10491 &amp;current_index, &amp;result, &amp;result_len);
10492 if (r == MAILIMF_NO_ERROR) {
10493
10494 /* do the things */
10495
10496 mailmime_decoded_part_free(mem);
10497 status = EXIT_SUCCESS;
10498 }
10499 }
10500 munmap(mem, stat_info.st_size);
10501 }
10502
10503 close(fd);
10504 }
10505
10506 exit(status);
10507}
10508 </programlisting>
10509 </example>
10510 </sect2>
10511
10512 <!-- mailmime_part_parse -->
10513 <sect2 id="mailmime-part-parse">
10514 <title>mailmime_part_parse</title>
10515
10516 <programlisting role="C">
10517#include &lt;libetpan/libetpan.h&gt;
10518
10519enum {
10520 MAILMIME_MECHANISM_ERROR,
10521 MAILMIME_MECHANISM_7BIT,
10522 MAILMIME_MECHANISM_8BIT,
10523 MAILMIME_MECHANISM_BINARY,
10524 MAILMIME_MECHANISM_QUOTED_PRINTABLE,
10525 MAILMIME_MECHANISM_BASE64,
10526 MAILMIME_MECHANISM_TOKEN
10527};
10528
10529int mailmime_part_parse(const char * message, size_t length,
10530 size_t * index,
10531 int encoding, char ** result, size_t * result_len);
10532 </programlisting>
10533
10534 <para>
10535 This function will parse a body part encoded using a
10536 given MIME encoding mechanism.
10537 </para>
10538
10539 <itemizedlist>
10540 <listitem>
10541 <para>
10542 <command>message</command> is a string encoded using
10543 binary.
10544 </para>
10545 </listitem>
10546 <listitem>
10547 <para>
10548 <command>length</command> is the size of the given
10549 string.
10550 </para>
10551 </listitem>
10552 <listitem>
10553 <para>
10554 <command>index</command> is a pointer to the start of
10555 the address in the given string, <command>(*
10556 index)</command> is modified to point at the end of the
10557 parsed data.
10558 </para>
10559 </listitem>
10560 <listitem>
10561 <para>
10562 <command>encoding</command> is a MIME encoding
10563 mechanism. The value can be
10564 <command>MAILMIME_MECHANISM_7BIT</command>,
10565 <command>MAILMIME_MECHANISM_8BIT</command>,
10566 <command>MAILMIME_MECHANISM_BINARY</command>,
10567 <command>MAILMIME_MECHANISM_QUOTED_PRINTABLE</command>,
10568 <command>MAILMIME_MECHANISM_BASE64</command> or
10569 <command>MAILMIME_MECHANISM_TOKEN</command>
10570 (see <xref linkend="mailmime-mechanism">).
10571 </para>
10572 </listitem>
10573 <listitem>
10574 <para>
10575 <command>result</command>. The result of the parse
10576 operation is stored in <command>(* result)</command>
10577 The result must be freed with
10578 <command>mmap_string_unref()</command>.
10579 </para>
10580 </listitem>
10581 </itemizedlist>
10582
10583 <example>
10584 <title>Parsing a MIME encoded part</title>
10585
10586 <programlisting role="C">
10587#include &lt;libetpan/libetpan.h&gt;
10588#include &lt;sys/stat.h&gt;
10589#include &lt;sys/mman.h&gt;
10590
10591int main(int argc, char ** argv)
10592{
10593 int fd;
10594 int r;
10595
10596 status = EXIT_FAILURE;
10597
10598 fd = open("message.rfc2822", O_RDONLY);
10599 if (fd &gt;= 0) {
10600 void * mem;
10601 struct stat stat_info;
10602
10603 r = fstat(fd, &amp;stat_info);
10604 if (r &gt;= 0) {
10605 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
10606 if (mem != MAP_FAILED) {
10607 struct mailimf_fields * f;
10608 size_t current_index;
10609 char * result;
10610 size_t result_len;
10611
10612 current_index = 0;
10613 r = mailmime_part_parse(mem, stat_info.st_size, &amp;current_index,
10614 MAILMIME_MECHANISM_QUOTED_PRINTABLE, &amp;result, &amp;result_len);
10615 if (r == MAILIMF_NO_ERROR) {
10616
10617 /* do the things */
10618
10619 mailmime_decoded_part_free(mem);
10620 status = EXIT_SUCCESS;
10621 }
10622 }
10623 munmap(mem, stat_info.st_size);
10624 }
10625
10626 close(fd);
10627 }
10628
10629 exit(status);
10630}
10631 </programlisting>
10632 </example>
10633 </sect2>
10634
10635 </sect1>
10636
10637 <sect1>
10638 <title>Rendering of MIME parts</title>
10639
10640 <!-- mailmime_fields_write -->
10641 <sect2 id="mailmime-fields-write">
10642 <title>mailmime_fields_write, mailmime_content_write and
10643 mailmime_content_type_write</title>
10644
10645 <programlisting role="C">
10646#include &lt;libetpan/libetpan.h&gt;
10647
10648int mailmime_fields_write(FILE * f, int * col,
10649 struct mailmime_fields * fields);
10650
10651int mailmime_content_write(FILE * f, int * col,
10652 struct mailmime_content * content);
10653
10654int mailmime_content_type_write(FILE * f, int * col,
10655 struct mailmime_content * content);
10656 </programlisting>
10657
10658 <para>
10659 <command>mailmime_fields_write</command> render the MIME
10660 header fields.
10661 </para>
10662
10663 <para>
10664 <command>mailmime_content_write</command> render the MIME
10665 content type header field.
10666 </para>
10667
10668 <para>
10669 <command>mailmime_content_write</command> render the
10670 content of the MIME content type header field.
10671 </para>
10672
10673 <itemizedlist>
10674 <listitem>
10675 <para>
10676 <command>col</command> current column is given for wrapping
10677 purpose in <command>(* col)</command>,
10678 the resulting columns will be returned..
10679 </para>
10680 </listitem>
10681 <listitem>
10682 <para>
10683 <command>f</command> is the file descriptor. It can be
10684 stdout for example.
10685 </para>
10686 </listitem>
10687 <listitem>
10688 <para>
10689 <command>fields</command> is the header fields
10690 (see <xref linkend="mailmime-fields">).
10691 </para>
10692 </listitem>
10693 <listitem>
10694 <para>
10695 <command>content</command> is the header fields
10696 (see <xref linkend="mailmime-content">).
10697 </para>
10698 </listitem>
10699 </itemizedlist>
10700
10701 <example>
10702 <title>rendering MIME header fields</title>
10703
10704 <programlisting role="C">
10705#include &lt;libetpan/libetpan.h&gt;
10706
10707int main(int argc, char ** argv)
10708{
10709 struct mailmime_mime * mime_fields;
10710 int col;
10711
10712 /* look at the example in mailmime_fields to see how to
10713 build a mailmime_fields */
10714 mime_fields = build_mime_fields();
10715
10716 col = 0;
10717 mailmime_fields_write(stdout, &amp;col, mime_fields);
10718
10719 mailmime_fields_free(mime_fields);
10720}
10721
10722int main(int argc, char ** argv)
10723{
10724 struct mailmime_content * content;
10725 int col;
10726
10727 /* look at the example in mailmime_content to see how to
10728 build a mailmime_fields */
10729 content = build_mime_content();
10730
10731 col = 0;
10732 mailmime_content_write(stdout, &amp;col, mime_fields);
10733
10734 mailmime_content_free(content);
10735}
10736
10737int main(int argc, char ** argv)
10738{
10739 struct mailmime_content * content;
10740 int col;
10741
10742 /* look at the example in mailmime_content to see how to
10743 build a mailmime_fields */
10744 content = build_mime_content();
10745
10746 col = 0;
10747 mailmime_content_type_write(stdout, &amp;col, mime_fields);
10748
10749 mailmime_content_free(content);
10750}
10751 </programlisting>
10752 </example>
10753 </sect2>
10754
10755 <!-- mailmime_write -->
10756 <sect2 id="mailmime-write">
10757 <title>mailmime_write</title>
10758
10759 <programlisting role="C">
10760#include &lt;libetpan/libetpan.h&gt;
10761
10762int mailmime_write(FILE * f, int * col,
10763 struct mailmime * build_info);
10764 </programlisting>
10765
10766 <para>
10767 This function will render a MIME message.
10768 </para>
10769
10770 <itemizedlist>
10771 <listitem>
10772 <para>
10773 <command>col</command> current column is given for wrapping
10774 purpose in <command>(* col)</command>,
10775 the resulting columns will be returned..
10776 </para>
10777 </listitem>
10778 <listitem>
10779 <para>
10780 <command>f</command> is the file descriptor. It can be
10781 stdout for example.
10782 </para>
10783 </listitem>
10784 <listitem>
10785 <para>
10786 <command>build_info</command> is the MIME message to
10787 render.
10788 </para>
10789 </listitem>
10790 </itemizedlist>
10791
10792 </sect2>
10793
10794 <!-- mailmime_quoted_printable_write -->
10795 <sect2 id="mailmime-quoted-printable-write">
10796 <title>mailmime_quoted_printable_write
10797 and mailmime_base64_write</title>
10798
10799 <programlisting role="C">
10800#include &lt;libetpan/libetpan.h&gt;
10801
10802int mailmime_quoted_printable_write(FILE * f, int * col, int istext,
10803 const char * text, size_t size);
10804
10805int mailmime_base64_write(FILE * f, int * col,
10806 const char * text, size_t size);
10807 </programlisting>
10808
10809 <para>
10810 <command>mailmime_quoted_printable_write()</command> will
10811 render a string to quoted printable.
10812 </para>
10813
10814 <para>
10815 <command>mailmime_base64_write()</command> will
10816 render a string to base64.
10817 </para>
10818
10819 <itemizedlist>
10820 <listitem>
10821 <para>
10822 <command>col</command> current column is given for wrapping
10823 purpose in <command>(* col)</command>,
10824 the resulting columns will be returned..
10825 </para>
10826 </listitem>
10827 <listitem>
10828 <para>
10829 <command>f</command> is the file descriptor. It can be
10830 stdout for example.
10831 </para>
10832 </listitem>
10833 <listitem>
10834 <para>
10835 <command>text</command> is the string to render.
10836 </para>
10837 </listitem>
10838 <listitem>
10839 <para>
10840 <command>size</command> is the size of the string to
10841 render.
10842 </para>
10843 </listitem>
10844 </itemizedlist>
10845
10846 <example>
10847 <title>render base64 or quoted printable</title>
10848
10849 <programlisting role="C">
10850#include &lt;libetpan/libetpan.h&gt;
10851
10852int main(int argc, char ** argv)
10853{
10854 int col;
10855
10856 col = 0;
10857 mailmime_quoted_printable_write(stdout, &amp;col,
10858 "this is a test", 14);
10859}
10860
10861#include &lt;libetpan/libetpan.h&gt;
10862
10863int main(int argc, char ** argv)
10864{
10865 int col;
10866
10867 col = 0;
10868 mailmime_base64_write(stdout, &amp;col, "this is a test", 14);
10869}
10870 </programlisting>
10871 </example>
10872 </sect2>
10873
10874 <!-- mailmime_data_write -->
10875 <sect2 id="mailmime-data-write">
10876 <title>mailmime_data_write</title>
10877
10878 <programlisting role="C">
10879#include &lt;libetpan/libetpan.h&gt;
10880
10881int mailmime_data_write(FILE * f, int * col,
10882 struct mailmime_data * data,
10883 int istext);
10884 </programlisting>
10885
10886 <para>
10887 <command>mailmime_data_write</command> will
10888 render MIME data.
10889 </para>
10890
10891 <itemizedlist>
10892 <listitem>
10893 <para>
10894 <command>col</command> current column is given for wrapping
10895 purpose in <command>(* col)</command>,
10896 the resulting columns will be returned..
10897 </para>
10898 </listitem>
10899 <listitem>
10900 <para>
10901 <command>f</command> is the file descriptor. It can be
10902 stdout for example.
10903 </para>
10904 </listitem>
10905 <listitem>
10906 <para>
10907 <command>data</command> is the data to render
10908 (see <xref linkend="mailmime-data">).
10909 </para>
10910 </listitem>
10911 </itemizedlist>
10912 </sect2>
10913 </sect1>
10914
10915 <!-- Creation functions -->
10916 <sect1>
10917 <title>Creation functions</title>
10918
10919 <!-- mailmime_disposition_new_filename -->
10920 <sect2 id="mailmime-disposition-new-filename">
10921 <title>mailmime_disposition_new_filename and
10922 mailmime_disposition_new_with_data</title>
10923
10924 <programlisting role="C">
10925#include &lt;libetpan/libetpan.h&gt;
10926
10927enum {
10928 MAILMIME_DISPOSITION_TYPE_ERROR,
10929 MAILMIME_DISPOSITION_TYPE_INLINE,
10930 MAILMIME_DISPOSITION_TYPE_ATTACHMENT,
10931 MAILMIME_DISPOSITION_TYPE_EXTENSION
10932};
10933
10934struct mailmime_disposition *
10935mailmime_disposition_new_filename(int type, char * filename);
10936
10937struct mailmime_disposition *
10938mailmime_disposition_new_with_data(int type,
10939 char * filename, char * creation_date, char * modification_date,
10940 char * read_date, size_t size);
10941 </programlisting>
10942
10943 <para>
10944 These functions will create a MIME content disposition
10945 information.
10946 </para>
10947
10948 <itemizedlist>
10949 <listitem>
10950 <para>
10951 <command>type</command> a standard MIME disposition :
10952 <command>MAILMIME_DISPOSITION_TYPE_INLINE</command> or
10953 <command>MAILMIME_DISPOSITION_TYPE_ATTACHMENT</command>.
10954 </para>
10955 <para>
10956 <command>filename</command> is the filename.
10957 </para>
10958 <para>
10959 <command>creation_date</command> is the creation date.
10960 </para>
10961 <para>
10962 <command>modification_date</command> is the modification
10963 date.
10964 </para>
10965 <para>
10966 <command>read_date</command> is the last read date.
10967 </para>
10968 <para>
10969 <command>size</command> is the size of the file.
10970 </para>
10971 </listitem>
10972 <listitem>
10973 <para>
10974 This will return a MIME content disposition
10975 (see <xref linkend="mailmime-disposition">).
10976 </para>
10977 </listitem>
10978 </itemizedlist>
10979
10980 <example>
10981 <title>creating a MIME content disposition</title>
10982
10983 <programlisting role="C">
10984#include &lt;libetpan/libetpan.h&gt;
10985
10986int main(int argc, char ** argv)
10987{
10988 struct mailmime_disposition * disposition;
10989
10990 disposition =
10991 mailmime_disposition_new_filename(MAILMIME_DISPOSITION_TYPE_ATTACHMENT,
10992 strdup("foo-bar.txt"));
10993
10994 /* do the things */
10995
10996 mailmime_disposition_free(disposition);
10997}
10998 </programlisting>
10999 </example>
11000 </sect2>
11001
11002 <!-- mailmime_fields_new_empty -->
11003 <sect2 id="mailmime-fields-new-empty">
11004 <title>mailmime_fields_new_empty and mailmime_fields_add</title>
11005
11006 <programlisting role="C">
11007#include &lt;libetpan/libetpan.h&gt;
11008
11009struct mailmime_fields * mailmime_fields_new_empty(void);
11010
11011int mailmime_fields_add(struct mailmime_fields * fields,
11012 struct mailmime_field * field);
11013 </programlisting>
11014
11015 <para>
11016 <command>mailmime_fields_new_empty()</command> will
11017 create a new empty MIME header fields list.
11018 </para>
11019
11020 <para>
11021 <command>mailmime_fields_add()</command> will add
11022 MIME header fields to the MIME header fields list.
11023 </para>
11024
11025 <itemizedlist>
11026 <listitem>
11027 <para>
11028 <command>fields</command>. The MIME header field will
11029 be added to this MIME header fields list
11030 (see <xref linkend="mailmime-fields">).
11031 </para>
11032 </listitem>
11033 <listitem>
11034 <para>
11035 <command>field</command> is the MIME header field to add
11036 (see <xref linkend="mailmime-field">).
11037 </para>
11038 </listitem>
11039 </itemizedlist>
11040
11041 <example>
11042 <title>creating a MIME header fields list</title>
11043
11044 <programlisting role="C">
11045#include &lt;libetpan/libetpan.h&gt;
11046
11047int main(int argc, char ** argv)
11048{
11049 struct mailmime_fields * fields;
11050 struct mailmime_field * field;
11051
11052 fields = mailmime_fields_new_empty();
11053 field = build_mime_field();
11054
11055 /* do the things */
11056
11057 mailmime_fields_add(fields, field);
11058
11059 mailmime_fields_free(fields);
11060}
11061 </programlisting>
11062 </example>
11063 </sect2>
11064
11065 <!-- mailmime_fields_new_with_data -->
11066 <sect2 id="mailmime-fields-new-with-data">
11067 <title>mailmime_fields_new_with_data and
11068 mailmime_fields_new_with_version</title>
11069
11070 <programlisting role="C">
11071#include &lt;libetpan/libetpan.h&gt;
11072
11073struct mailmime_fields *
11074mailmime_fields_new_with_data(struct mailmime_mechanism * encoding,
11075 char * id,
11076 char * description,
11077 struct mailmime_disposition * disposition,
11078 struct mailmime_language * language);
11079
11080struct mailmime_fields *
11081mailmime_fields_new_with_version(struct mailmime_mechanism * encoding,
11082 char * id,
11083 char * description,
11084 struct mailmime_disposition * disposition,
11085 struct mailmime_language * language);
11086 </programlisting>
11087
11088 <para>
11089 <command>mailmime_fields_new_with_data()</command> will
11090 create a MIME header fields list with all the given fields
11091 (<command>NULL</command> can be used for the value if the
11092 field must not be present).
11093 <command>MIME-Version</command> header field will
11094 <emphasis>not</emphasis> be added.
11095 </para>
11096
11097 <para>
11098 <command>mailmime_fields_new_with_version()</command> will
11099 create a MIME header fields list with all the given fields
11100 (<command>NULL</command> can be used for the value if the
11101 field must not be present).
11102 <command>MIME-Version</command> header field will be added.
11103 </para>
11104
11105 <example>
11106 <title>creating new fields</title>
11107
11108 <programlisting role="C">
11109#include &lt;libetpan/libetpan.h&gt;
11110
11111int main(int argc, char ** argv)
11112{
11113 struct mailmime_disposition * disposition;
11114 struct mailmime_fields * mime_fields;
11115 struct mailmime_mechanism * encoding;
11116
11117 encoding = mailmime_mechanism_new(MAILMIME_MECHANISM_BASE64, NULL);
11118
11119 disposition =
11120 mailmime_disposition_new_filename(MAILMIME_DISPOSITION_TYPE_ATTACHMENT,
11121 strdup("foo-bar.txt"));
11122
11123 mime_fields = mailmime_fields_new_with_version(encoding, NULL,
11124 NULL, disposition, NULL);
11125
11126 /* do the things */
11127
11128 mailmime_fields_free(mime_fields);
11129}
11130 </programlisting>
11131 </example>
11132 </sect2>
11133
11134 <!-- mailmime_get_content_message -->
11135 <sect2 id="mailmime-get-content-message">
11136 <title>mailmime_get_content_message</title>
11137
11138 <programlisting role="C">
11139#include &lt;libetpan/libetpan.h&gt;
11140
11141struct mailmime_content * mailmime_get_content_message(void);
11142
11143struct mailmime_content * mailmime_get_content_text(void);
11144
11145struct mailmime_content * mailmime_content_new_with_str(const char * str);
11146 </programlisting>
11147
11148 <para>
11149 <command>mailmime_get_content_message()</command> will
11150 create a MIME content type
11151 <command>message/rfc822</command>.
11152 </para>
11153
11154 <para>
11155 <command>mailmime_get_content_text()</command> will
11156 create a MIME content type
11157 <command>plain/text</command>.
11158 </para>
11159
11160 <para>
11161 <command>mailmime_get_content_new_with_str()</command> will
11162 create a MIME content type given by the string
11163 <command>plain/text</command>.
11164 </para>
11165
11166 <para>
11167 <command>str</command>. This string will
11168 <command>NOT</command> be referenced by any structure.
11169 This string will only be parsed to create the structure.
11170 </para>
11171
11172 <example>
11173 <title>Creating a MIME content type</title>
11174
11175 <programlisting role="C">
11176#include &lt;libetpan/libetpan.h&gt;
11177
11178int main(int argc, char ** argv)
11179{
11180 struct mailmime_content * content;
11181
11182 content = mailmime_get_content_message();
11183
11184 /* do the things */
11185
11186 mailmime_content_free(content);
11187}
11188
11189int main(int argc, char ** argv)
11190{
11191 struct mailmime_content * content;
11192
11193 content = mailmime_get_content_text();
11194
11195 /* do the things */
11196
11197 mailmime_content_free(content);
11198}
11199
11200int main(int argc, char ** argv)
11201{
11202 struct mailmime_content * content;
11203
11204 content = mailmime_get_content_new_with_str("multipart/mixed");
11205
11206 /* do the things */
11207
11208 mailmime_content_free(content);
11209}
11210 </programlisting>
11211 </example>
11212 </sect2>
11213
11214 <!-- mailmime_data_new_data -->
11215 <sect2 id="mailmime-data-new-data">
11216 <title>mailmime_data_new_data and mailmime_data_new_file</title>
11217
11218 <programlisting role="C">
11219#include &lt;libetpan/libetpan.h&gt;
11220
11221enum {
11222 MAILMIME_MECHANISM_ERROR,
11223 MAILMIME_MECHANISM_7BIT,
11224 MAILMIME_MECHANISM_8BIT,
11225 MAILMIME_MECHANISM_BINARY,
11226 MAILMIME_MECHANISM_QUOTED_PRINTABLE,
11227 MAILMIME_MECHANISM_BASE64,
11228 MAILMIME_MECHANISM_TOKEN
11229};
11230
11231struct mailmime_data *
11232mailmime_data_new_data(int encoding, int encoded,
11233 const char * data, size_t length);
11234
11235struct mailmime_data *
11236mailmime_data_new_file(int encoding, int encoded,
11237 char * filename);
11238 </programlisting>
11239
11240 <para>
11241 <command>mailmime_data_new_data()</command> will create a
11242 new MIME content, using a string in memory.
11243 </para>
11244
11245 <para>
11246 <command>mailmime_data_new_file()</command> will create a
11247 new MIME content, using a file.
11248 </para>
11249
11250 <itemizedlist>
11251 <listitem>
11252 <para>
11253 <command>encoding</command> is the MIME encoding
11254 mechanism used to encode this part. The value can be
11255 <command>MAILMIME_MECHANISM_7BIT</command>,
11256 <command>MAILMIME_MECHANISM_8BIT</command>,
11257 <command>MAILMIME_MECHANISM_BINARY</command>,
11258 <command>MAILMIME_MECHANISM_QUOTED_PRINTABLE</command> or
11259 <command>MAILMIME_MECHANISM_BASE64</command>
11260 (see <xref linkend="mailmime-mechanism">).
11261 </para>
11262 </listitem>
11263 <listitem>
11264 <para>
11265 <command>encoded</command> is set to 1 if the part is
11266 already encoded with the mechanism given in
11267 <command>encoding</command>.
11268 </para>
11269 </listitem>
11270 <listitem>
11271 <para>
11272 <command>data</command> is a pointer to the
11273 content of the part.
11274 </para>
11275 </listitem>
11276 <listitem>
11277 <para>
11278 <command>length</command> is the length of the data.
11279 </para>
11280 </listitem>
11281 <listitem>
11282 <para>
11283 <command>filename</command> is the name of the file.
11284 </para>
11285 </listitem>
11286 </itemizedlist>
11287
11288 <example>
11289 <title>creating MIME content</title>
11290
11291 <programlisting role="C">
11292#include &lt;libetpan/libetpan.h&gt;
11293
11294#define DATA_STR "my data"
11295
11296int main(int argc, char ** argv)
11297{
11298 struct mailmime_data * data;
11299
11300 data = mailmime_data_new_data(MAILMIME_MECHANISM_BASE64, 0,
11301 DATA_STR, sizeof(DATA_STR) - 1);
11302
11303 /* do the things */
11304
11305 mailmime_data_free(data);
11306}
11307
11308int main(int argc, char ** argv)
11309{
11310 struct mailmime_data * data;
11311
11312 data = mailmime_data_new_file(MAILMIME_MECHANISM_BASE64, 0,
11313 strdup("foo-bar.txt"));
11314
11315 /* do the things */
11316
11317 mailmime_data_free(data);
11318}
11319 </programlisting>
11320 </example>
11321 </sect2>
11322
11323 <!-- mailmime_new_message_data -->
11324 <sect2 id="mailmime-new-message-data">
11325 <title>mailmime_new_message_data, mailmime_new_empty and
11326 mailmime_new_with_content</title>
11327
11328 <programlisting role="C">
11329#include &lt;libetpan/libetpan.h&gt;
11330
11331struct mailmime *
11332mailmime_new_message_data(struct mailmime * msg_mime);
11333
11334struct mailmime *
11335mailmime_new_empty(struct mailmime_content * content,
11336 struct mailmime_fields * mime_fields);
11337
11338int
11339mailmime_new_with_content(const char * content_type,
11340 struct mailmime_fields * mime_fields,
11341 struct mailmime ** result);
11342
11343struct mailmime * mailmime_multiple_new(const char * type);
11344 </programlisting>
11345
11346 <para>
11347 <command>mailmime_new_message_data()</command> will create a
11348 new MIME message with the given subpart.
11349 </para>
11350
11351 <para>
11352 <command>mailmime_new_empty()</command> will create a
11353 new MIME part with the given content type and MIME fields
11354 but with no content.
11355 </para>
11356
11357 <para>
11358 <command>mailmime_new_with_content()</command> will create a
11359 new MIME part with a content type given by a string and a
11360 given MIME fields list.
11361 </para>
11362
11363 <para>
11364 <command>mailmime_multiple_new()</command> will create a
11365 new MIME multipart with a content type given by a string.
11366 </para>
11367
11368 <itemizedlist>
11369 <listitem>
11370 <para>
11371 <command>msg_mime</command> is the sub part to add to the
11372 MIME message when creating it
11373 (see <xref linkend="mailmime">).
11374 </para>
11375 </listitem>
11376 <listitem>
11377 <para>
11378 <command>content</command> is the content type of the part
11379 to create
11380 (see <xref linkend="mailmime-content">).
11381 </para>
11382 </listitem>
11383 <listitem>
11384 <para>
11385 <command>content_type</command> is the content type of
11386 the part to create given by a string.
11387 </para>
11388 </listitem>
11389 <listitem>
11390 <para>
11391 <command>mime_fields</command> is the list of MIME
11392 header fields
11393 (see <xref linkend="mailmime-fields">).
11394 </para>
11395 </listitem>
11396 </itemizedlist>
11397
11398 <example>
11399 <title>creating a MIME part</title>
11400
11401 <programlisting role="C">
11402#include &lt;libetpan/libetpan.h&gt;
11403
11404#define DATA_STR "my data"
11405
11406int main(int argc, char ** argv)
11407{
11408 struct mailmime * mime;
11409 struct mailmime * single_part;
11410
11411 mime_fields =
11412 mailmime_fields_new_encoding(MAILMIME_MECHANISM_QUOTED_PRINTABLE);
11413 mailmime_new_with_content("plain/text", mime_fields, &amp;single_part);
11414
11415 mailmime_set_body_text(single_part, DATA_STR, sizeof(DATA_STR) - 1);
11416
11417 mime = mailmime_new_message_data(single_part);
11418
11419 /* do the things */
11420
11421 mailmime_free(mime);
11422}
11423
11424int main(int argc, char ** argv)
11425{
11426 struct mailmime * mime;
11427 struct mailmime * single_part;
11428 struct mailmime_content * content;
11429
11430 mime_fields =
11431 mailmime_fields_new_encoding(MAILMIME_MECHANISM_QUOTED_PRINTABLE);
11432 content = mailmime_get_content_text();
11433 single_part = mailmime_new_empty(content, mime_fields);
11434
11435 mailmime_set_body_text(single_part, DATA_STR, sizeof(DATA_STR) - 1);
11436
11437 mime = mailmime_new_message_data(single_part);
11438
11439 /* do the things */
11440
11441 mailmime_free(mime);
11442}
11443
11444int main(int argc, char ** argv)
11445{
11446 struct mailmime * mime;
11447
11448 mime = mailmime_multiple_new("multipart/mixed");
11449
11450 /* do the things */
11451
11452 mailmime_free(mime);
11453}
11454 </programlisting>
11455 </example>
11456 </sect2>
11457
11458 <!-- mailmime_set_preamble_file -->
11459 <sect2 id="mailmime-set-preamble-file">
11460 <title>mailmime_set_preamble_file, mailmime_set_epilogue_file,
11461 mailmime_set_preamble_text and mailmime_set_epilogue_text</title>
11462
11463 <programlisting role="C">
11464#include &lt;libetpan/libetpan.h&gt;
11465
11466int mailmime_set_preamble_file(struct mailmime * build_info,
11467 char * filename);
11468
11469int mailmime_set_epilogue_file(struct mailmime * build_info,
11470 char * filename);
11471
11472int mailmime_set_preamble_text(struct mailmime * build_info,
11473 char * data_str, size_t length);
11474
11475int mailmime_set_epilogue_text(struct mailmime * build_info,
11476 char * data_str, size_t length);
11477 </programlisting>
11478
11479 <para>
11480 <command>mailmime_set_preamble_file()</command> will define
11481 the preamble of a multipart.
11482 </para>
11483
11484 <para>
11485 <command>mailmime_set_preamble_text()</command> will define
11486 the preamble of a multipart.
11487 </para>
11488
11489 <para>
11490 <command>mailmime_set_epilogue_file()</command> will define
11491 the epilogue of a multipart.
11492 </para>
11493
11494 <para>
11495 <command>mailmime_set_preamble_text()</command> will define
11496 the preamble of a multipart.
11497 </para>
11498
11499 <itemizedlist>
11500 <listitem>
11501 <para>
11502 <command>build_info</command> is the MIME part to modify
11503 (see <xref linkend="mailmime">).
11504 </para>
11505 </listitem>
11506 <listitem>
11507 <para>
11508 <command>data_str</command> is the string to define
11509 as epilogue or prologue.
11510 </para>
11511 </listitem>
11512 <listitem>
11513 <para>
11514 <command>length</command> is the length of the string to
11515 define as epilogue or prologue.
11516 </para>
11517 </listitem>
11518 <listitem>
11519 <para>
11520 <command>filename</command> is the name of the file
11521 which content will be defined as epilogue or prologue.
11522 </para>
11523 </listitem>
11524 </itemizedlist>
11525
11526 <example>
11527 <title>setting preamble and epilogue</title>
11528
11529 <programlisting role="C">
11530#include &lt;libetpan/libetpan.h&gt;
11531
11532#define DATA_STR "test foo bar"
11533
11534int main(int argc, char ** argv)
11535{
11536 struct mailmime * mime;
11537
11538 mime = mailmime_multiple_new("multipart/mixed");
11539
11540 mailmime_set_preamble_file(mime, strdup("foo-bar.txt"));
11541
11542 mailmime_set_epilogue_data(mime, DATA_STR, sizeof(DATA_STR) - 1);
11543
11544 /* do the things */
11545
11546 mailmime_free(mime);
11547}
11548 </programlisting>
11549 </example>
11550 </sect2>
11551
11552 <!-- mailmime_set_body_file -->
11553 <sect2 id="mailmime-set-body-file">
11554 <title>mailmime_set_body_file and mailmime_set_body_text</title>
11555
11556 <programlisting role="C">
11557#include &lt;libetpan/libetpan.h&gt;
11558
11559int mailmime_set_body_file(struct mailmime * build_info,
11560 char * filename);
11561
11562int mailmime_set_body_text(struct mailmime * build_info,
11563 char * data_str, size_t length);
11564 </programlisting>
11565
11566 <para>
11567 <command>mailmime_set_body_file()</command> will define
11568 the body of a single part.
11569 </para>
11570
11571 <para>
11572 <command>mailmime_set_body_text()</command> will define
11573 the body of a single part.
11574 </para>
11575
11576 <itemizedlist>
11577 <listitem>
11578 <para>
11579 <command>build_info</command> is the MIME part to modify
11580 (see <xref linkend="mailmime">).
11581 </para>
11582 </listitem>
11583 <listitem>
11584 <para>
11585 <command>data_str</command> is the string to define
11586 as the body of the part.
11587 </para>
11588 </listitem>
11589 <listitem>
11590 <para>
11591 <command>length</command> is the length of the string to
11592 define as the body of the part.
11593 </para>
11594 </listitem>
11595 <listitem>
11596 <para>
11597 <command>filename</command> is the name of the file
11598 which content will be defined as the body of the part.
11599 </para>
11600 </listitem>
11601 </itemizedlist>
11602
11603 <example>
11604 <title>creating a MIME part</title>
11605
11606 <programlisting role="C">
11607#include &lt;libetpan/libetpan.h&gt;
11608
11609#define DATA_STR "my data"
11610
11611int main(int argc, char ** argv)
11612{
11613 struct mailmime * mime;
11614
11615 mime_fields =
11616 mailmime_fields_new_encoding(MAILMIME_MECHANISM_QUOTED_PRINTABLE);
11617 mailmime_new_with_content("plain/text", mime_fields, &amp;mime);
11618
11619 mailmime_set_body_text(mime, DATA_STR, sizeof(DATA_STR) - 1);
11620
11621
11622
11623 /* do the things */
11624
11625 mailmime_free(mime);
11626}
11627 </programlisting>
11628 </example>
11629
11630 </sect2>
11631
11632 <!-- mailmime_add_part -->
11633 <sect2 id="mailmime-add-part">
11634 <title>mailmime_add_part, mailmime_remove_part,
11635 mailmime_smart_add_part and mailmime_smart_remove_part</title>
11636
11637 <programlisting role="C">
11638#include &lt;libetpan/libetpan.h&gt;
11639
11640int mailmime_add_part(struct mailmime * build_info,
11641 struct mailmime * part);
11642
11643void mailmime_remove_part(struct mailmime * mime);
11644
11645int mailmime_smart_add_part(struct mailmime * mime,
11646 struct mailmime * mime_sub);
11647
11648int mailmime_smart_remove_part(struct mailmime * mime);
11649 </programlisting>
11650
11651 <para>
11652 <command>mailmime_add_part()</command> will add a sub MIME
11653 part.
11654 </para>
11655
11656 <para>
11657 <command>mailmime_remove_part()</command> will detach the
11658 given sub part from its parent.
11659 </para>
11660
11661 <para>
11662 <command>mailmime_smart_add_part()</command> will add a sub
11663 MIME part. If the parent part is a message and no child
11664 exist, the part is set as the child. If the parent part is a
11665 message and a child already exists, if the child is
11666 multipart, the part to add is added as child of this
11667 multipart, else a multipart is added and the part is added
11668 as child of the multipart.
11669 </para>
11670
11671 <para>
11672 <command>mailmime_smart_remove_part()</command> will detach
11673 the given sub part from its parent. The sub part will be
11674 freed.
11675 </para>
11676
11677 <itemizedlist>
11678 <listitem>
11679 <para>
11680 <command>build_info</command> is the parent MIME part
11681 (see <xref linkend="mailmime">).
11682 </para>
11683 </listitem>
11684 <listitem>
11685 <para>
11686 <command>part</command> is the part to add
11687 (see <xref linkend="mailmime">).
11688 </para>
11689 </listitem>
11690 <listitem>
11691 <para>
11692 <command>mime</command> is the parent MIME part
11693 (see <xref linkend="mailmime">).
11694 </para>
11695 </listitem>
11696 <listitem>
11697 <para>
11698 <command>mime_sub</command> is the part to add or to
11699 detach
11700 (see <xref linkend="mailmime">).
11701 </para>
11702 </listitem>
11703 </itemizedlist>
11704
11705 <example>
11706 <title>modifying MIME structure</title>
11707
11708 <programlisting role="C">
11709#include &lt;libetpan/libetpan.h&gt;
11710
11711int main(int argc, char ** argv)
11712{
11713 struct mailmime * sub_mime;
11714 struct mailmime_fields * mime_fields;
11715 struct mailmime_content * content;
11716
11717 content = mailmime_get_content_text();
11718
11719 mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_BASE64);
11720
11721 sub_mime = mailmime_new_empty(content, mime_fields);
11722
11723 mime = mailmime_new_message_data(NULL);
11724
11725 mailmime_add_part(mime, sub_mime);
11726
11727 /* do the things */
11728
11729 mailmime_free(mime);
11730
11731int main(int argc, char ** argv)
11732{
11733 struct mailmime * sub_mime;
11734 struct mailmime * other_sub_mime;
11735 struct mailmime_fields * mime_fields;
11736 struct mailmime_content * content;
11737
11738 content = mailmime_get_content_text();
11739 mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_BASE64);
11740 sub_mime = mailmime_new_empty(content, mime_fields);
11741
11742 content = mailmime_get_content_text();
11743 mime_fields =
11744 mailmime_fields_new_encoding(MAILMIME_MECHANISM_QUOTED_PRINTABLE);
11745 other_sub_mime = mailmime_new_empty(content, mime_fields);
11746
11747 mime = mailmime_new_message_data(NULL);
11748
11749 mailmime_smart_add_part(mime, sub_mime);
11750 mailmime_smart_add_part(mime, other_sub_mime);
11751
11752 /* do the things */
11753
11754 mailmime_free(mime);
11755
11756int main(int argc, char ** argv)
11757{
11758 struct mailmime * sub_mime;
11759 struct mailmime_fields * mime_fields;
11760 struct mailmime_content * content;
11761
11762 content = mailmime_get_content_text();
11763
11764 mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_BASE64);
11765
11766 sub_mime = mailmime_new_empty(content, mime_fields);
11767
11768 mime = mailmime_new_message_data(NULL);
11769
11770 mailmime_add_part(mime, sub_mime);
11771
11772 mailmime_remove_part(sub_mime);
11773
11774 /* do the things */
11775
11776 mailmime_free(sub_mime);
11777 mailmime_free(mime);
11778
11779int main(int argc, char ** argv)
11780{
11781 struct mailmime * sub_mime;
11782 struct mailmime_fields * mime_fields;
11783 struct mailmime_content * content;
11784
11785 content = mailmime_get_content_text();
11786
11787 mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_BASE64);
11788
11789 sub_mime = mailmime_new_empty(content, mime_fields);
11790
11791 mime = mailmime_new_message_data(NULL);
11792
11793 mailmime_add_part(mime, sub_mime);
11794
11795 mailmime_smart_remove_part(sub_mime);
11796
11797 /* do the things */
11798
11799 mailmime_free(mime);
11800}
11801 </programlisting>
11802 </example>
11803 </sect2>
11804
11805 <!-- mailmime_set_imf_fields -->
11806 <sect2 id="mailmime-set-imf-fields">
11807 <title>mailmime_set_imf_fields</title>
11808
11809 <programlisting role="C">
11810#include &lt;libetpan/libetpan.h&gt;
11811
11812void mailmime_set_imf_fields(struct mailmime * build_info,
11813 struct mailimf_fields * fields);
11814 </programlisting>
11815
11816 <para>
11817 <command>mailmime_set_imf_fields()</command> will set the
11818 fields of the given MIME message.
11819 </para>
11820
11821 <itemizedlist>
11822 <listitem>
11823 <para>
11824 <command>build_info</command> is the MIME message to
11825 modify
11826 (see <xref linkend="mailmime">).
11827 </para>
11828 </listitem>
11829 <listitem>
11830 <para>
11831 <command>fields</command> is the header fields to set
11832 for the message
11833 (see <xref linkend="mailimf-fields">).
11834 </para>
11835 </listitem>
11836 </itemizedlist>
11837
11838 <example>
11839 <title>modifying MIME structure</title>
11840
11841 <programlisting role="C">
11842#include &lt;libetpan/libetpan.h&gt;
11843
11844#define DATA_STR "test foo bar"
11845
11846int main(int argc, char ** argv)
11847{
11848 struct mailmime * mime;
11849 struct mailmime_fields * mime_fields;
11850 struct mailimf_fields * imf_fields;
11851
11852 mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT);
11853
11854 mailmime_new_with_content("text/plain", mime_fields, &amp;mime);
11855
11856 mailmime_set_body_text(mime, DATA_STR, sizeof(DATA_STR) - 1);
11857
11858 /* look at the example in mailimf_fields to see how to
11859 build a mailimf_fields */
11860 imf_fields = build_fields();
11861
11862 mailmime_set_imf_fields(mime, imf_fields);
11863
11864 /* do the things */
11865
11866 mailmime_free(mime);
11867}
11868 </programlisting>
11869 </example>
11870 </sect2>
11871
11872 <!-- mailmime_fields_new_encoding -->
11873 <sect2 id="mailmime-fields-new-encoding">
11874 <title>mailmime_fields_new_encoding and
11875 mailmime_fields_new_filename</title>
11876
11877 <programlisting role="C">
11878#include &lt;libetpan/libetpan.h&gt;
11879
11880enum {
11881 MAILMIME_MECHANISM_ERROR,
11882 MAILMIME_MECHANISM_7BIT,
11883 MAILMIME_MECHANISM_8BIT,
11884 MAILMIME_MECHANISM_BINARY,
11885 MAILMIME_MECHANISM_QUOTED_PRINTABLE,
11886 MAILMIME_MECHANISM_BASE64,
11887 MAILMIME_MECHANISM_TOKEN
11888};
11889
11890enum {
11891 MAILMIME_DISPOSITION_TYPE_ERROR,
11892 MAILMIME_DISPOSITION_TYPE_INLINE,
11893 MAILMIME_DISPOSITION_TYPE_ATTACHMENT,
11894 MAILMIME_DISPOSITION_TYPE_EXTENSION
11895};
11896
11897struct mailmime_fields * mailmime_fields_new_encoding(int encoding_type);
11898
11899struct mailmime_fields * mailmime_fields_new_filename(int dsp_type,
11900 char * filename, int encoding_type);
11901 </programlisting>
11902
11903 <para>
11904 <command>mailmime_fields_new_encoding()</command> will
11905 create a list of MIME header fields with only
11906 <command>Content-Transfer-Encoding</command>.
11907 </para>
11908
11909 <para>
11910 <command>mailmime_fields_new_filename()</command> will
11911 create a list of MIME header fields with
11912 <command>Content-Transfer-Encoding</command> and
11913 <command>Content-Disposition</command>.
11914 </para>
11915
11916 <para>
11917 The result will be a list of MIME header fields
11918 (see <xref linkend="mailmime-fields">).
11919 </para>
11920
11921 <itemizedlist>
11922 <listitem>
11923 <para>
11924 <command>encoding_type</command> is the MIME encoding
11925 mechanism. The value can be
11926 <command>MAILMIME_MECHANISM_7BIT</command>,
11927 <command>MAILMIME_MECHANISM_8BIT</command>,
11928 <command>MAILMIME_MECHANISM_BINARY</command>,
11929 <command>MAILMIME_MECHANISM_QUOTED_PRINTABLE</command> or
11930 <command>MAILMIME_MECHANISM_BASE64</command>
11931 (see <xref linkend="mailmime-mechanism">).
11932 </para>
11933 </listitem>
11934 <listitem>
11935 <para>
11936 <command>dsp_type</command> is the disposition type.
11937 The value can be
11938 <command>MAILMIME_DISPOSITION_TYPE_INLINE</command> or
11939 <command>MAILMIME_DISPOSITION_TYPE_ATTACHMENT</command>
11940 (see <xref linkend="mailmime-disposition-type">).
11941 </para>
11942 </listitem>
11943 <listitem>
11944 <para>
11945 <command>filename</command> is the filename for MIME
11946 content disposition.
11947 </para>
11948 </listitem>
11949 </itemizedlist>
11950
11951 <example>
11952 <title>creating MIME fields with only Content-Transfer-Encoding</title>
11953
11954 <programlisting role="C">
11955#include &lt;libetpan/libetpan.h&gt;
11956
11957int main(void)
11958{
11959 struct mailmime_fields * fields;
11960
11961 fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_BASE64);
11962
11963 /* do the things */
11964
11965 mailmime_fields_free(fields);
11966}
11967
11968int main(void)
11969{
11970 struct mailmime_fields * fields;
11971
11972 fields =
11973 mailmime_fields_new_filename(MAILMIME_DISPOSITION_TYPE_ATTACHMENT,
11974 strdup("foo-bar.txt"), MAILMIME_MECHANISM_BASE64);
11975
11976 /* do the things */
11977
11978 mailmime_fields_free(fields);
11979}
11980 </programlisting>
11981 </example>
11982 </sect2>
11983 </sect1>
11984
11985 <!-- Helper functions -->
11986 <sect1>
11987 <title>Helper functions</title>
11988
11989 <!-- mailmime_transfer_encoding_get -->
11990 <sect2 id="mailmime-transfer-encoding-get">
11991 <title>mailmime_transfer_encoding_get</title>
11992
11993 <programlisting role="C">
11994#include &lt;libetpan/libetpan.h&gt;
11995
11996int mailmime_transfer_encoding_get(struct mailmime_fields * fields);
11997 </programlisting>
11998
11999 <para>
12000 <command>mailmime_transfer_encoding_get()</command> will
12001 return the standard MIME encoding mechanism.
12002 </para>
12003
12004 <itemizedlist>
12005 <listitem>
12006 <para>
12007 <command>fields</command> is the list of MIME header
12008 fields.
12009 </para>
12010 </listitem>
12011 <listitem>
12012 <para>
12013 An integer representing the MIME encoding mechanism will
12014 be returned
12015 (see <xref linkend="mailmime-mechanism">).
12016 </para>
12017 </listitem>
12018 </itemizedlist>
12019
12020 <example>
12021 <title>extracting MIME encoding mechanism</title>
12022
12023 <programlisting role="C">
12024#include &lt;libetpan/libetpan.h&gt;
12025#include &lt;sys/stat.h&gt;
12026#include &lt;sys/mman.h&gt;
12027
12028int main(int argc, char ** argv)
12029{
12030 int fd;
12031 int r;
12032
12033 status = EXIT_FAILURE;
12034
12035 fd = open("message.rfc2822", O_RDONLY);
12036 if (fd &gt;= 0) {
12037 void * mem;
12038 struct stat stat_info;
12039
12040 r = fstat(fd, &amp;stat_info);
12041 if (r &gt;= 0) {
12042 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
12043 if (mem != MAP_FAILED) {
12044 struct mailimf_fields * f;
12045 size_t current_index;
12046
12047 current_index = 0;
12048 r = mailimf_fields_parse(mem, stat_info.st_size,
12049 &amp;current_index, &amp;f);
12050 if (r == MAILIMF_NO_ERROR) {
12051 struct mailmime_fields * mime_fields;
12052
12053 r = mailmime_fields_parse(f, &amp;mime_fields);
12054 if (r == MAILIMF_NO_ERROR) {
12055 int encoding;
12056
12057 encoding = mailmime_transfer_encoding_get(mime_fields);
12058
12059 /* do the things */
12060
12061 mailmime_fields_free(mime_fields);
12062 status = EXIT_SUCCESS;
12063 }
12064
12065 mailimf_fields_free(f);
12066 }
12067 }
12068 munmap(mem, stat_info.st_size);
12069 }
12070
12071 close(fd);
12072 }
12073
12074 exit(status);
12075}
12076 </programlisting>
12077 </example>
12078
12079 </sect2>
12080
12081 <!-- mailmime_content_charset_get -->
12082 <sect2 id="mailmime-content-charset-get">
12083 <title>mailmime_content_charset_get and
12084 mailmime_content_param_get</title>
12085
12086 <programlisting role="C">
12087#include &lt;libetpan/libetpan.h&gt;
12088
12089char * mailmime_content_charset_get(struct mailmime_content * content);
12090
12091char * mailmime_content_param_get(struct mailmime_content * content,
12092 char * name);
12093
12094char * mailmime_extract_boundary(struct mailmime_content * content_type);
12095 </programlisting>
12096
12097 <para>
12098 <command>mailmime_content_charset_get()</command> will
12099 return the <command>charset</command> parameter of
12100 MIME content type.
12101 </para>
12102
12103 <para>
12104 <command>mailmime_content_param_get()</command> will
12105 return the value of a given parameter of
12106 MIME content type.
12107 </para>
12108
12109 <para>
12110 <command>mailmime_extract_boundary()</command> will
12111 return the <command>charset</command> parameter of
12112 MIME content type.
12113 </para>
12114
12115 <itemizedlist>
12116 <listitem>
12117 <para>
12118 <command>content</command> is the MIME content type.
12119 </para>
12120 </listitem>
12121 <listitem>
12122 <para>
12123 <command>name</command> is the name of the parameter to
12124 extract.
12125 </para>
12126 </listitem>
12127 <listitem>
12128 <para>
12129 With <command>mailmime_extract_boundary()</command>, the
12130 returned value must be freed with
12131 <command>free()</command>.
12132 </para>
12133 </listitem>
12134 </itemizedlist>
12135
12136 <example>
12137 <title>extracting information from MIME content type</title>
12138
12139 <programlisting role="C">
12140#include &lt;libetpan/libetpan.h&gt;
12141#include &lt;sys/stat.h&gt;
12142#include &lt;sys/mman.h&gt;
12143
12144int main(int argc, char ** argv)
12145{
12146 int fd;
12147 int r;
12148
12149 status = EXIT_FAILURE;
12150
12151 fd = open("message.rfc2822", O_RDONLY);
12152 if (fd &gt;= 0) {
12153 void * mem;
12154 struct stat stat_info;
12155
12156 r = fstat(fd, &amp;stat_info);
12157 if (r &gt;= 0) {
12158 mem = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE);
12159 if (mem != MAP_FAILED) {
12160 struct mailimf_fields * f;
12161 size_t current_index;
12162
12163 current_index = 0;
12164 r = mailimf_fields_parse(mem, stat_info.st_size,
12165 &amp;current_index, &amp;f);
12166 if (r == MAILIMF_NO_ERROR) {
12167 clistiter * cur;
12168
12169 for(cur = clist_begin(f-&gt;fld_list) ; cur != NULL ; cur =
12170 clist_next(cur)) {
12171 struct mailmime_field * mime_field;
12172 struct mailimf_field * field;
12173
12174 field = clist_content(cur);
12175
12176 if (field-&gt;fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
12177 if (strcasecmp(field-&gt;fld_data.fld_optional_field-&gt;fld_name,
12178 "Content-Type") == 0) {
12179 struct mailmime_content * content_type;
12180 size_t current_index;
12181
12182 current_index = 0;
12183 r = mailmime_content_parse(field-&gt;fld_data.fld_optional_field-&gt;fld_value,
12184 strlen(field-&gt;fld_data.fld_optional_field-&gt;fld_value),
12185 &amp;current_index, &amp;content_type);
12186 if (r == MAILIMF_NO_ERROR) {
12187 char * charset;
12188 char * name;
12189 char * boundary;
12190
12191 charset = mailmime_content_charset_get(content_type);
12192 name = mailmime_content_param_get(content_type, "name");
12193 boundary = mailmime_extract_boundary(content_type);
12194
12195 /* do the things */
12196
12197 free(boundary);
12198
12199 status = EXIT_SUCCESS;
12200 mailmime_content_free(content_type);
12201 }
12202 }
12203 }
12204 }
12205 mailimf_fields_free(f);
12206 }
12207 }
12208 munmap(mem, stat_info.st_size);
12209 }
12210
12211 close(fd);
12212 }
12213
12214 exit(status);
12215}
12216 </programlisting>
12217 </example>
12218 </sect2>
12219 </sect1>
12220 </chapter>
12221
12222 <!-- Storages, folders, messages -->
12223 <chapter>
12224 <title>Storages, folders, messages</title>
12225
12226 <!-- Introduction -->
12227 <sect1>
12228 <title>Introduction</title>
12229
12230 <para>
12231 This part will give the definition of some objects.
12232 </para>
12233
12234 <sect2>
12235 <title>Message</title>
12236
12237 <para>
12238 A message is the common e-mail message or news message you
12239 read or send.
12240 </para>
12241 </sect2>
12242
12243 <sect2>
12244 <title>MIME part</title>
12245
12246 <para>
12247 A message can have attachment such as images or other documents.
12248 The attachment are organized into a tree structure. Each
12249 node of this structure is a MIME part.
12250 </para>
12251 </sect2>
12252
12253 <sect2>
12254 <title>Mailbox</title>
12255
12256 <para>
12257 A mailbox will contain a given number of messages.
12258 </para>
12259 </sect2>
12260
12261 <sect2>
12262 <title>Storage</title>
12263
12264 <para>
12265 A storage is a "physical" localisation of your mailbox. This
12266 can be on a filesystem (local or remote disk, this is the
12267 case of MH, mbox and maildir), or this can be on a remote
12268 host (this is the case for POP3, IMAP or NNTP).
12269 </para>
12270 </sect2>
12271
12272 <sect2>
12273 <title>Folder</title>
12274
12275 <para>
12276 A storage, for the same user, can contain a given number of
12277 mailboxes, depending the storage capabilities, then, the
12278 storage driver capabilities. With etPan!, MH, IMAP and NNTP
12279 storages can have more than one mailbox. The mailboxes will
12280 be called folders. On storage where we only have one
12281 mailbox, the unique mailbox is the unique folder.
12282 </para>
12283 </sect2>
12284
12285 <sect2>
12286 <title>Session</title>
12287
12288 <para>
12289 The session is the network connection or the entity to which
12290 the commands of the drivers are given.
12291 </para>
12292 </sect2>
12293 </sect1>
12294
12295 <sect1>
12296 <title>Error codes</title>
12297
12298 <para>
12299 Error codes returned as integers can be one of the following :
12300 </para>
12301
12302 <programlisting role="C">
12303enum {
12304 MAIL_NO_ERROR = 0,
12305 MAIL_NO_ERROR_AUTHENTICATED,
12306 MAIL_NO_ERROR_NON_AUTHENTICATED,
12307 MAIL_ERROR_NOT_IMPLEMENTED,
12308 MAIL_ERROR_UNKNOWN,
12309 MAIL_ERROR_CONNECT,
12310 MAIL_ERROR_BAD_STATE,
12311 MAIL_ERROR_FILE,
12312 MAIL_ERROR_STREAM,
12313 MAIL_ERROR_LOGIN,
12314 MAIL_ERROR_CREATE, /* 10 */
12315 MAIL_ERROR_DELETE,
12316 MAIL_ERROR_LOGOUT,
12317 MAIL_ERROR_NOOP,
12318 MAIL_ERROR_RENAME,
12319 MAIL_ERROR_CHECK,
12320 MAIL_ERROR_EXAMINE,
12321 MAIL_ERROR_SELECT,
12322 MAIL_ERROR_MEMORY,
12323 MAIL_ERROR_STATUS,
12324 MAIL_ERROR_SUBSCRIBE, /* 20 */
12325 MAIL_ERROR_UNSUBSCRIBE,
12326 MAIL_ERROR_LIST,
12327 MAIL_ERROR_LSUB,
12328 MAIL_ERROR_APPEND,
12329 MAIL_ERROR_COPY,
12330 MAIL_ERROR_FETCH,
12331 MAIL_ERROR_STORE,
12332 MAIL_ERROR_SEARCH,
12333 MAIL_ERROR_DISKSPACE,
12334 MAIL_ERROR_MSG_NOT_FOUND, /* 30 */
12335 MAIL_ERROR_PARSE,
12336 MAIL_ERROR_INVAL,
12337 MAIL_ERROR_PART_NOT_FOUND,
12338 MAIL_ERROR_REMOVE,
12339 MAIL_ERROR_FOLDER_NOT_FOUND,
12340 MAIL_ERROR_MOVE,
12341 MAIL_ERROR_STARTTLS,
12342 MAIL_ERROR_CACHE_MISS,
12343 MAIL_ERROR_NO_TLS,
12344 MAIL_ERROR_EXPUNGE,
12345 /* misc errors */
12346 MAIL_ERROR_MISC,
12347 MAIL_ERROR_PROTOCOL,
12348 MAIL_ERROR_CAPABILITY,
12349 MAIL_ERROR_CLOSE,
12350 MAIL_ERROR_FATAL,
12351 MAIL_ERROR_READONLY,
12352 MAIL_ERROR_NO_APOP,
12353 MAIL_ERROR_COMMAND_NOT_SUPPORTED,
12354 MAIL_ERROR_NO_PERMISSION,
12355 MAIL_ERROR_PROGRAM_ERROR,
12356 MAIL_ERROR_SUBJECT_NOT_FOUND,
12357 MAIL_ERROR_CHAR_ENCODING_FAILED,
12358 MAIL_ERROR_SEND,
12359 MAIL_ERROR_COMMAND,
12360};
12361 </programlisting>
12362 </sect1>
12363
12364 <!-- Storage -->
12365 <sect1>
12366 <title>Storage</title>
12367
12368 <sect2 id="mailstorage-driver">
12369 <title>Storage driver</title>
12370
12371 <programlisting role="C">
12372#include &lt;libetpan/libetpan.h&gt;
12373
12374typedef struct mailstorage_driver mailstorage_driver;
12375
12376struct mailstorage_driver {
12377 char * sto_name;
12378 int (* sto_connect)(struct mailstorage * storage);
12379 int (* sto_get_folder_session)(struct mailstorage * storage,
12380 char * pathname, mailsession ** result);
12381 void (* sto_uninitialize)(struct mailstorage * storage);
12382};
12383 </programlisting>
12384
12385 <para>
12386 This is the driver for a storage.
12387 </para>
12388
12389 <itemizedlist>
12390 <listitem>
12391 <para>
12392 <command>sto_name</command> is the name of the driver.
12393 </para>
12394 </listitem>
12395 <listitem>
12396 <para>
12397 <command>sto_connect()</command> connects the storage to
12398 the remote access or to the path in the local filesystem.
12399 </para>
12400 </listitem>
12401 <listitem>
12402 <para>
12403 <command>sto_get_folder_session()</command> can have two
12404 kinds of behaviour. Either it creates a new session and
12405 independant from the session used by the storage and
12406 select the given mailbox or it selects the given mailbox
12407 in the current session. It depends on the efficiency of
12408 the mail access.
12409 </para>
12410 <para>
12411 <emphasis>XXX - in the future, this will be moved to the
12412 folder driver</emphasis>
12413 </para>
12414 </listitem>
12415 <listitem>
12416 <para>
12417 <command>sto_uninitialize()</command> frees the data
12418 created with mailstorage constructor.
12419 </para>
12420 </listitem>
12421 </itemizedlist>
12422 </sect2>
12423
12424 <sect2 id="mailstorage">
12425 <title>Storage</title>
12426
12427 <programlisting role="C">
12428#include &lt;libetpan/libetpan.h&gt;
12429
12430struct mailstorage {
12431 char * sto_id;
12432 void * sto_data;
12433 mailsession * sto_session;
12434 mailstorage_driver * sto_driver;
12435 clist * sto_shared_folders; /* list of (struct mailfolder *) */
12436
12437 void * sto_user_data;
12438};
12439 </programlisting>
12440
12441 <itemizedlist>
12442 <listitem>
12443 <para>
12444 <command>sto_id</command> is an identifier for the
12445 storage. This can be <command>NULL</command>.
12446 </para>
12447 </listitem>
12448 <listitem>
12449 <para>
12450 <command>sto_data</command> is the internal data
12451 of the storage. This can only be changed by the driver.
12452 </para>
12453 </listitem>
12454 <listitem>
12455 <para>
12456 <command>sto_session</command> is the session used by
12457 the storage. The session can be used to send commands.
12458 </para>
12459 </listitem>
12460 <listitem>
12461 <para>
12462 <command>sto_driver</command> is the driver of the
12463 storage.
12464 </para>
12465 </listitem>
12466 <listitem>
12467 <para>
12468 <command>sto_shared_folders</command> is the list of
12469 folders that share the session with the storage.
12470 This is used internally.
12471 </para>
12472 </listitem>
12473 <listitem>
12474 <para>
12475 <command>sto_user_data</command> is a field for free
12476 use. The user can store any data in that field.
12477 </para>
12478 </listitem>
12479 </itemizedlist>
12480 </sect2>
12481
12482 <sect2 id="mailstorage-new">
12483 <title>mailstorage_new and mailstorage_free</title>
12484
12485 <programlisting role="C">
12486#include &lt;libetpan/libetpan.h&gt;
12487
12488struct mailstorage * mailstorage_new(char * sto_id);
12489
12490void mailstorage_free(struct mailstorage * storage);
12491 </programlisting>
12492
12493 <para>
12494 <command>mailstorage_new()</command> initializes a storage
12495 structure with an identifier (<command>sto_id</command>) and
12496 with no driver.
12497 </para>
12498
12499 <para>
12500 <command>mailstorage_free()</command> free the memory used
12501 by a storage.
12502 </para>
12503 </sect2>
12504
12505 <sect2 id="mailstorage-connect">
12506 <title>mailstorage_connect and mailstorage_disconnect</title>
12507
12508 <programlisting role="C">
12509#include &lt;libetpan/libetpan.h&gt;
12510
12511int mailstorage_connect(struct mailstorage * storage);
12512
12513void mailstorage_disconnect(struct mailstorage * storage);
12514 </programlisting>
12515
12516 <para>
12517 <command>mailstorage_connect()</command> connects the storage.
12518 This function can also be used to confirm that a storage
12519 connection is valid when the storage is already connected.
12520 </para>
12521
12522 <para>
12523 <command>mailstorage_disconnect()</command> disconnects the
12524 storage.
12525 </para>
12526 </sect2>
12527
12528 <sect2>
12529 <title>IMAP storage</title>
12530
12531 <programlisting role="C">
12532int imap_mailstorage_init(struct mailstorage * storage,
12533 char * imap_servername, uint16_t imap_port,
12534 char * imap_command,
12535 int imap_connection_type, int imap_auth_type,
12536 char * imap_login, char * imap_password,
12537 int imap_cached, char * imap_cache_directory);
12538 </programlisting>
12539 </sect2>
12540
12541 <sect2>
12542 <title>Example</title>
12543
12544 <example>
12545 <title>use of storage</title>
12546
12547 <programlisting role="C">
12548int main(void)
12549{
12550 struct mailstorage * storage;
12551 int r;
12552
12553 storage = mailstorage_new(NULL);
12554
12555 imap_mailstorage_init(storage, "imap.my-servers.org", 0,
12556 NULL, CONNECTION_TYPE_TRY_STARTTLS, IMAP_AUTH_TYPE_PLAIN,
12557 "my-login", "my-password", 1, "/home/login/.libetpan/cache");
12558
12559 r = mailstorage_connect(storage);
12560 if (r == MAIL_NO_ERROR) {
12561 mailstorage_disconnect(storage);
12562 }
12563
12564 mailstorage_free(storage);
12565}
12566 </programlisting>
12567 </example>
12568 </sect2>
12569 </sect1>
12570
12571 <!-- Folder -->
12572 <sect1>
12573 <title>Folder</title>
12574
12575 <sect2 id="mailfolder-driver">
12576 <title>Folder driver</title>
12577
12578 <programlisting role="C">
12579#include &lt;libetpan/libetpan.h&gt;
12580
12581typedef struct mailfolder_driver mailfolder_driver;
12582
12583struct mailfolder_driver {
12584 int (* fld_get_session)(struct mailfolder * folder,
12585 mailsession ** result);
12586
12587 int (* fld_noop)(struct mailfolder * folder);
12588
12589 int (* fld_check)(struct mailfolder * folder);
12590
12591 int (* fld_expunge)(struct mailfolder * folder);
12592
12593 int (* fld_status)(struct mailfolder * folder,
12594 uint32_t * result_messages, uint32_t * result_recent,
12595 uint32_t * result_unseen);
12596
12597 int (* fld_append_message)(struct mailfolder * folder,
12598 char * message, size_t size);
12599
12600 int (* fld_get_messages_list)(struct mailfolder * folder,
12601 struct mailmessage_list ** result);
12602
12603 int (* fld_get_envelopes_list)(struct mailfolder * folder,
12604 struct mailmessage_list * result);
12605
12606 int (* fld_get_message)(struct mailfolder * folder,
12607 uint32_t num, mailmessage ** result);
12608
12609 int (* fld_get_message_by_uid)(struct mailfolder * folder,
12610 const char * uid, mailmessage ** result);
12611}
12612 </programlisting>
12613
12614 <para>
12615 XXX - this will be implemented in the future.
12616 </para>
12617
12618 <itemizedlist>
12619 <listitem>
12620 <para>
12621 <command>fld_get_session()</command> will return the session
12622 this folder should use.
12623 </para>
12624 </listitem>
12625 <listitem>
12626 <para>
12627 For other method, you should see <xref
12628 linkend="mailsession-driver">.
12629 </para>
12630 </listitem>
12631 </itemizedlist>
12632 </sect2>
12633
12634 <sect2>
12635 <title>Folder</title>
12636
12637 <programlisting role="C">
12638#include &lt;libetpan/libetpan.h&gt;
12639
12640struct mailfolder {
12641 char * fld_pathname;
12642 char * fld_virtual_name;
12643
12644 struct mailstorage * fld_storage;
12645
12646 mailsession * fld_session;
12647 int fld_shared_session;
12648 clistiter * fld_pos;
12649
12650 struct mailfolder * fld_parent;
12651 unsigned int fld_sibling_index;
12652 carray * fld_children; /* array of (struct mailfolder *) */
12653
12654 void * fld_user_data;
12655};
12656 </programlisting>
12657
12658 <itemizedlist>
12659 <listitem>
12660 <para>
12661 <command>fld_pathname</command> is the pathname specific to
12662 the driver.
12663 </para>
12664 </listitem>
12665
12666 <listitem>
12667 <para>
12668 <command>fld_virtual_name</command> is the identifier of
12669 this folder. This can be <command>NULL</command>.
12670 </para>
12671 </listitem>
12672
12673 <listitem>
12674 <para>
12675 <command>fld_storage</command> is the storage used for this
12676 folder (see <xref linkend="mailstorage">).
12677 </para>
12678 </listitem>
12679
12680 <listitem>
12681 <para>
12682 <command>fld_session</command> is the session used for this
12683 folder.
12684 </para>
12685 </listitem>
12686
12687 <listitem>
12688 <para>
12689 <command>fld_shared_session</command> is set to 1 if the
12690 folder use the same session as the storage. This is used
12691 internally.
12692 </para>
12693 </listitem>
12694
12695 <listitem>
12696 <para>
12697 <command>fld_pos</command> is the
12698 position in the list of folders of the storage.
12699 This is used internally.
12700 </para>
12701 </listitem>
12702
12703 <listitem>
12704 <para>
12705 use of <command>fld_parent</command>,
12706 <command>fld_sibling_index</command> and
12707 <command>fld_children</command> is deprecated.
12708 </para>
12709 </listitem>
12710
12711 <listitem>
12712 <para>
12713 <command>fld_user_data</command> is a field for free
12714 use. The user can store any data in that field.
12715 </para>
12716 </listitem>
12717 </itemizedlist>
12718 </sect2>
12719
12720 <sect2 id="mailfolder-new">
12721 <title>mailfolder_new and mail_folder_free</title>
12722
12723 <programlisting role="C">
12724#include &lt;libetpan/libetpan.h&gt;
12725
12726struct mailfolder * mailfolder_new(struct mailstorage * fld_storage,
12727 char * fld_pathname, char * fld_virtual_name);
12728
12729void mailfolder_free(struct mailfolder * folder);
12730 </programlisting>
12731
12732 <para>
12733 <command>mailfolder_new()</command> initializes a folder
12734 structure with an identifier
12735 (<command>fld_virtual_name</command>) with path name
12736 (<command>fld_pathname</command>). The folder will be owned
12737 by the given storage (<command>fld_storage</command>).
12738 </para>
12739
12740 <para>
12741 <command>mailfolder_free()</command> free the memory used
12742 by the folder.
12743 </para>
12744 </sect2>
12745
12746 <sect2 id="mailfolder-connect">
12747 <title>mailfolder_connect and mailfolder_disconnect</title>
12748
12749 <programlisting role="C">
12750#include &lt;libetpan/libetpan.h&gt;
12751
12752int mailfolder_connect(struct mailfolder * folder);
12753
12754void mailfolder_disconnect(struct mailfolder * folder);
12755 </programlisting>
12756
12757 <para>
12758 <command>mailfolder_connect()</command> connects the folder.
12759 This function can also be used to confirm that a folder
12760 connection is valid when the folder is already connected.
12761 When doing operations with several folders, you have to be
12762 sure that this function has been called before making calls
12763 on folder.
12764 </para>
12765
12766 <para>
12767 <command>mailfolder_disconnect()</command> disconnects the
12768 folder.
12769 </para>
12770 </sect2>
12771
12772 <sect2 id="mailfolder-noop">
12773 <title>mailfolder_noop</title>
12774
12775 <programlisting role="C">
12776#include &lt;libetpan/libetpan.h&gt;
12777
12778int mailfolder_noop(struct mailfolder * folder);
12779 </programlisting>
12780
12781 <para>
12782 This function will only send noop to the mail access.
12783 </para>
12784 </sect2>
12785
12786 <sect2 id="mailfolder-check">
12787 <title>mailfolder_check</title>
12788
12789 <programlisting role="C">
12790#include &lt;libetpan/libetpan.h&gt;
12791
12792int mailfolder_check(struct mailfolder * folder);
12793 </programlisting>
12794
12795 <para>
12796 A call to this function will save to disk the internal state
12797 of the selected mailbox (such as flags).
12798 </para>
12799 </sect2>
12800
12801 <sect2 id="mailfolder-expunge">
12802 <title>mailfolder_expunge</title>
12803
12804 <programlisting role="C">
12805#include &lt;libetpan/libetpan.h&gt;
12806
12807int mailfolder_expunge(struct mailfolder * folder);
12808 </programlisting>
12809
12810 <para>
12811 A call to this function will delete all messages marked for
12812 deletion.
12813 </para>
12814 </sect2>
12815
12816 <sect2 id="mailfolder-status">
12817 <title>mailfolder_status</title>
12818
12819 <programlisting role="C">
12820int mailfolder_status(struct mailfolder * folder,
12821 uint32_t * result_messages, uint32_t * result_recent,
12822 uint32_t * result_unseen);
12823 </programlisting>
12824
12825 <para>
12826 A call to this function will return some counts of messages
12827 in the mailbox.
12828 </para>
12829 </sect2>
12830
12831 <sect2 id="mailfolder-append-message">
12832 <title>mailfolder_append_message</title>
12833
12834 <programlisting role="C">
12835int mailfolder_append_message(struct mailfolder * folder,
12836 char * message, size_t size);
12837 </programlisting>
12838
12839 <para>
12840 This function will store a new message in the given folder.
12841 The message is given by a string in memory
12842 (<command>message</command>) and a size
12843 (<command>size</command>).
12844 </para>
12845 </sect2>
12846
12847 <sect2 id="mailfolder-get-messages-list">
12848 <title>mailfolder_get_messages_list</title>
12849
12850 <programlisting role="C">
12851int mailfolder_get_messages_list(struct mailfolder * folder,
12852 struct mailmessage_list ** result);
12853 </programlisting>
12854
12855 <para>
12856 This function will return the list of messages in the given
12857 folder (see <xref linkend="mailmessage-list">).
12858 </para>
12859 </sect2>
12860
12861 <sect2 id="mailfolder-get-envelopes-list">
12862 <title>mailfolder_get_envelopes_list</title>
12863
12864 <programlisting role="C">
12865int mailfolder_get_envelopes_list(struct mailfolder * folder,
12866 struct mailmessage_list * result);
12867 </programlisting>
12868
12869 <para>
12870 This function will fill the list of parsed header fields
12871 structure in the <command>mailmessage</command> structures
12872 of the given list of messages (<command>result</command>).
12873 </para>
12874 </sect2>
12875
12876 <sect2 id="mailfolder-get-message">
12877 <title>mailfolder_get_message</title>
12878
12879 <programlisting role="C">
12880int mailfolder_get_message(struct mailfolder * folder,
12881 uint32_t num, mailmessage ** result);
12882 </programlisting>
12883
12884 <para>
12885 This function will return the message identified by a
12886 message index (<command>num</command>)
12887 This will return a <command>mailmessage</command> structure
12888 in <command>(* result)</command> (see <xref
12889 linkend="mailmessage">).
12890 </para>
12891 </sect2>
12892
12893 <sect2 id="mailfolder-get-message-by-uid">
12894 <title>mailfolder_get_message_by_uid</title>
12895
12896 <programlisting role="C">
12897int mailfolder_get_message_by_uid(struct mailfolder * folder,
12898 const char * uid, mailmessage ** result);
12899 </programlisting>
12900
12901 <para>
12902 This function will return the message identified by a
12903 unique identifier (<command>uid</command>)
12904 This will return a <command>mailmessage</command> structure
12905 in <command>(* result)</command> (see <xref
12906 linkend="mailmessage">).
12907 </para>
12908 </sect2>
12909
12910 <sect2>
12911 <title>Example</title>
12912
12913 <example>
12914 <title>use of folder</title>
12915
12916 <programlisting role="C">
12917int main(void)
12918{
12919 struct mailstorage * storage;
12920 int r;
12921
12922 storage = mailstorage_new(NULL);
12923
12924 imap_mailstorage_init(storage, "imap.my-servers.org", 0,
12925 NULL, CONNECTION_TYPE_TRY_STARTTLS, IMAP_AUTH_TYPE_PLAIN,
12926 "my-login", "my-password", 1, "/home/login/.libetpan/cache");
12927
12928 r = mailstorage_connect(storage);
12929 if (r == MAIL_NO_ERROR) {
12930 struct mailfolder * folder;
12931
12932 folder = mailfolder_new(storage, "INBOX", NULL);
12933
12934 r = mailfolder_connect(folder);
12935 if (r == MAIL_NO_ERROR) {
12936 struct mailmessage_list * msg_list;
12937
12938 mailfolder_get_messages_list(folder, &amp;msg_list);
12939
12940 /* do the things */
12941
12942 mailmessage_list_free(msg_list);
12943
12944 mailfolder_disconnect(folder);
12945 }
12946
12947 mailstorage_disconnect(storage);
12948 }
12949
12950 mailstorage_free(storage);
12951}
12952 </programlisting>
12953 </example>
12954 </sect2>
12955
12956 </sect1>
12957
12958 <!-- Message -->
12959 <sect1>
12960 <title>Message</title>
12961
12962 <sect2 id="mailmessage-driver">
12963 <title>Message driver</title>
12964
12965 <programlisting role="C">
12966#include &lt;libetpan/libetpan.h&gt;
12967
12968struct mailmessage_driver {
12969 char * msg_name;
12970
12971 int (* msg_initialize)(mailmessage * msg_info);
12972
12973 void (* msg_uninitialize)(mailmessage * msg_info);
12974
12975 void (* msg_flush)(mailmessage * msg_info);
12976
12977 void (* msg_check)(mailmessage * msg_info);
12978
12979 void (* msg_fetch_result_free)(mailmessage * msg_info,
12980 char * msg);
12981
12982 int (* msg_fetch)(mailmessage * msg_info,
12983 char ** result,
12984 size_t * result_len);
12985
12986 int (* msg_fetch_header)(mailmessage * msg_info,
12987 char ** result,
12988 size_t * result_len);
12989
12990 int (* msg_fetch_body)(mailmessage * msg_info,
12991 char ** result, size_t * result_len);
12992
12993 int (* msg_fetch_size)(mailmessage * msg_info,
12994 size_t * result);
12995
12996 int (* msg_get_bodystructure)(mailmessage * msg_info,
12997 struct mailmime ** result);
12998
12999 int (* msg_fetch_section)(mailmessage * msg_info,
13000 struct mailmime * mime,
13001 char ** result, size_t * result_len);
13002
13003 int (* msg_fetch_section_header)(mailmessage * msg_info,
13004 struct mailmime * mime,
13005 char ** result,
13006 size_t * result_len);
13007
13008 int (* msg_fetch_section_mime)(mailmessage * msg_info,
13009 struct mailmime * mime,
13010 char ** result,
13011 size_t * result_len);
13012
13013 int (* msg_fetch_section_body)(mailmessage * msg_info,
13014 struct mailmime * mime,
13015 char ** result,
13016 size_t * result_len);
13017
13018 int (* msg_fetch_envelope)(mailmessage * msg_info,
13019 struct mailimf_fields ** result);
13020
13021 int (* msg_get_flags)(mailmessage * msg_info,
13022 struct mail_flags ** result);
13023};
13024 </programlisting>
13025
13026 <itemizedlist>
13027 <listitem>
13028 <para>
13029 <command>msg_name</command> is the name of the driver.
13030 </para>
13031 </listitem>
13032
13033 <listitem>
13034 <para>
13035 <command>msg_initialize()</command> will initialize the
13036 internal message state (field
13037 <command>msg_data</command> of
13038 <command>mailmessage</command> structure (see <xref
13039 linkend="mailmessage">).
13040 </para>
13041 </listitem>
13042
13043 <listitem>
13044 <para>
13045 <command>msg_uninitialize()</command> will free the
13046 internal message state.
13047 </para>
13048 </listitem>
13049
13050 <listitem>
13051 <para>
13052 <command>msg_flush()</command> will release memory used
13053 by the MIME structure of the message.
13054 </para>
13055 </listitem>
13056
13057 <listitem>
13058 <para>
13059 <command>msg_check()</command> will store the flags of
13060 the message into the session, so that the message can be
13061 released without the flags are lost.
13062 </para>
13063 </listitem>
13064
13065 <listitem>
13066 <para>
13067 <command>msg_fetch_result_free()</command> will free a
13068 string returned by any fetch_XXX() function.
13069 </para>
13070 </listitem>
13071
13072 <listitem>
13073 <para>
13074 <command>msg_fetch()</command> will fetch a message.
13075 </para>
13076 </listitem>
13077
13078 <listitem>
13079 <para>
13080 <command>msg_fetch_header()</command> will fetch the
13081 header fields of a message.
13082 </para>
13083 </listitem>
13084
13085 <listitem>
13086 <para>
13087 <command>msg_fetch_body()</command> will fetch a message
13088 without its main header.
13089 </para>
13090 </listitem>
13091
13092 <listitem>
13093 <para>
13094 <command>msg_fetch_size()</command> will return the size
13095 of a message.
13096 </para>
13097 </listitem>
13098
13099 <listitem>
13100 <para>
13101 <command>msg_get_bodystructure</command> will retrieve
13102 the MIME structure of the message. The returned
13103 structure must <emphasis>NOT</emphasis> be freed.
13104 </para>
13105 </listitem>
13106
13107 <listitem>
13108 <para>
13109 <command>msg_fetch_section()</command> will fetch the
13110 content of the section of the message.
13111 </para>
13112 </listitem>
13113
13114 <listitem>
13115 <para>
13116 <command>msg_fetch_section_header()</command> will fetch
13117 the header of a section of the message if the content of
13118 the section is a message.
13119 </para>
13120 </listitem>
13121
13122 <listitem>
13123 <para>
13124 <command>msg_fetch_section_mime()</command> will fetch
13125 the MIME header of a section of the message.
13126 </para>
13127 </listitem>
13128
13129 <listitem>
13130 <para>
13131 <command>msg_fetch_section_body()</command> will fetch
13132 the body of a section (without the headers) of the
13133 message if the content of the section is a message.
13134 </para>
13135 </listitem>
13136
13137 <listitem>
13138 <para>
13139 <command>msg_fetch_envelope()</command> will return
13140 a given number of parsed header fields.
13141 </para>
13142 </listitem>
13143
13144 <listitem>
13145 <para>
13146 <command>msg_get_flags()</command> will return the
13147 flags of the message.
13148 The returned structure must <emphasis>NOT</emphasis> be
13149 freed.
13150 </para>
13151 </listitem>
13152 </itemizedlist>
13153 </sect2>
13154
13155 <sect2 id="mailmessage">
13156 <title>Message</title>
13157
13158 <programlisting role="C">
13159#include &lt;libetpan/libetpan.h&gt;
13160
13161struct mailmessage {
13162 mailsession * msg_session;
13163 mailmessage_driver * msg_driver;
13164 uint32_t msg_index;
13165 char * msg_uid;
13166
13167 size_t msg_size;
13168 struct mailimf_fields * msg_fields;
13169 struct mail_flags * msg_flags;
13170
13171 int msg_resolved;
13172 struct mailimf_single_fields msg_single_fields;
13173 struct mailmime * msg_mime;
13174
13175 /* internal data */
13176
13177 int msg_cached;
13178 void * msg_data;
13179
13180 /*
13181 msg_folder field :
13182 used to reference the mailfolder, this is a workaround due
13183 to the problem with initial conception, where folder notion
13184 did not exist.
13185 */
13186 void * msg_folder;
13187 /* user data */
13188 void * msg_user_data;
13189};
13190 </programlisting>
13191
13192 <itemizedlist>
13193 <listitem>
13194 <para>
13195 <command>msg_session</command> is the session related to
13196 the message
13197 (see <xref linkend="mailsession">).
13198 </para>
13199 </listitem>
13200
13201 <listitem>
13202 <para>
13203 <command>msg_driver</command> is the driver used for the
13204 message
13205 (see <xref linkend="mailmessage-driver">).
13206 </para>
13207 </listitem>
13208
13209 <listitem>
13210 <para>
13211 <command>msg_index</command> is an index to indentify
13212 the message.
13213 </para>
13214 </listitem>
13215
13216 <listitem>
13217 <para>
13218 <command>msg_uid</command> is the unique identifier of
13219 the message, valid accross disconnections.
13220 </para>
13221 </listitem>
13222
13223 <listitem>
13224 <para>
13225 <command>msg_size</command> is the size of the message.
13226 </para>
13227 </listitem>
13228
13229 <listitem>
13230 <para>
13231 <command>msg_fields</command> is the list of parsed
13232 header fields of the message. This can be
13233 <command>NULL</command>
13234 (see <xref linkend="mailimf-fields">).
13235 </para>
13236 </listitem>
13237
13238 <listitem>
13239 <para>
13240 <command>msg_flags</command> is the flags of the
13241 message. This can be <command>NULL</command>
13242 (see <xref linkend="mail-flags">).
13243 </para>
13244 </listitem>
13245
13246 <listitem>
13247 <para>
13248 <command>msg_resolved</command> will tell if the field
13249 <command>msg_single_fields</command> has been initialized.
13250 </para>
13251 </listitem>
13252
13253 <listitem>
13254 <para>
13255 <command>msg_single_fields</command> will be filled
13256 using <command>msg_fields</command>
13257 (see <xref linkend="mailimf-single-fields">).
13258 </para>
13259 </listitem>
13260
13261 <listitem>
13262 <para>
13263 <command>msg_mime</command> is the MIME structure of the
13264 message. It is intialized at least when
13265 <command>get_bodystructure()</command> is called once.
13266 </para>
13267 </listitem>
13268
13269 <listitem>
13270 <para>
13271 <command>msg_cached</command> is 1 when the message was
13272 cached. This is used internally.
13273 </para>
13274 </listitem>
13275
13276 <listitem>
13277 <para>
13278 <command>msg_data</command> is the internal state of the
13279 message. The content depends on the driver.
13280 </para>
13281 </listitem>
13282
13283 <listitem>
13284 <para>
13285 <command>msg_folder</command> is used to reference the
13286 mailfolder, this is a workaround due to the problem with
13287 initial conception, where folder notion did not exist.
13288 </para>
13289 </listitem>
13290
13291 <listitem>
13292 <para>
13293 <command>msg_user_data</command> is a field for free
13294 use. The user can store any data in that field.
13295 </para>
13296 </listitem>
13297 </itemizedlist>
13298 </sect2>
13299
13300 <sect2 id="mailmessage-new">
13301 <title>mailmessage_new</title>
13302
13303 <programlisting role="C">
13304#include &lt;libetpan/libetpan.h&gt;
13305
13306mailmessage * mailmessage_new(void);
13307
13308void mailmessage_free(mailmessage * info);
13309 </programlisting>
13310
13311 <para>
13312 <command>mailmessage_new()</command> will create a new
13313 message (without driver). This is used internally by
13314 drivers.
13315 </para>
13316
13317 <para>
13318 <command>mailmessage_free()</command> will free the memory
13319 used by the given message.
13320 </para>
13321 </sect2>
13322
13323 <sect2 id="mailmessage-init">
13324 <title>mailmessage_init</title>
13325
13326 <programlisting role="C">
13327#include &lt;libetpan/libetpan.h&gt;
13328
13329int mailmessage_init(mailmessage * msg_info,
13330 mailsession * session,
13331 mailmessage_driver * driver,
13332 uint32_t index, size_t size);
13333 </programlisting>
13334
13335 <para>
13336 <command>mailmessage_init()</command> will initialize a
13337 message with a driver.
13338 </para>
13339
13340 <itemizedlist>
13341 <listitem>
13342 <para>
13343 <command>msg_info</command> is the message to initialize
13344 (see <xref linkend="mailmessage">).
13345 </para>
13346 </listitem>
13347
13348 <listitem>
13349 <para>
13350 <command>session</command> is the session related to the
13351 message
13352 (see <xref linkend="mailsession">).
13353 </para>
13354 </listitem>
13355
13356 <listitem>
13357 <para>
13358 <command>driver</command> is the driver to use for the
13359 message
13360 (see <xref linkend="mailmessage-driver">).
13361 </para>
13362 </listitem>
13363
13364 <listitem>
13365 <para>
13366 <command>index</command> is the index of the message.
13367 </para>
13368 </listitem>
13369
13370 <listitem>
13371 <para>
13372 <command>size</command> is the size of the message.
13373 </para>
13374 </listitem>
13375 </itemizedlist>
13376 </sect2>
13377
13378 <sect2 id="mailmessage-flush">
13379 <title>mailmessage_flush</title>
13380
13381 <programlisting role="C">
13382#include &lt;libetpan/libetpan.h&gt;
13383
13384int mailmessage_flush(mailmessage * info);
13385 </programlisting>
13386
13387 <para>
13388 This function will release the memory used by the MIME
13389 structure of the message.
13390 </para>
13391 </sect2>
13392
13393 <sect2 id="mailmessage-check">
13394 <title>mailmessage_check</title>
13395
13396 <programlisting role="C">
13397#include &lt;libetpan/libetpan.h&gt;
13398
13399int mailmessage_check(mailmessage * info);
13400 </programlisting>
13401
13402 <para>
13403 After you set some flags, if you want to notify them to the
13404 session before destroying the message, you can use this function.
13405 </para>
13406 </sect2>
13407
13408 <sect2 id="mailmessage-fetch-result-free">
13409 <title>mailmessage_fetch_result_free</title>
13410
13411 <programlisting role="C">
13412#include &lt;libetpan/libetpan.h&gt;
13413
13414int mailmessage_fetch_result_free(mailmessage * msg_info,
13415 char * msg);
13416 </programlisting>
13417
13418 <para>
13419 This function will free a string returned by any
13420 mailmessage_fetch_XXX() function.
13421 </para>
13422 </sect2>
13423
13424 <sect2 id="mailmessage-fetch">
13425 <title>mailmessage_fetch</title>
13426
13427 <programlisting role="C">
13428#include &lt;libetpan/libetpan.h&gt;
13429
13430int mailmessage_fetch(mailmessage * msg_info,
13431 char ** result,
13432 size_t * result_len);
13433 </programlisting>
13434
13435 <para>
13436 This function returns the content of the message (headers
13437 and text).
13438 </para>
13439 </sect2>
13440
13441 <sect2 id="mailmessage-fetch-header">
13442 <title>mailmessage_fetch_header</title>
13443
13444 <programlisting role="C">
13445#include &lt;libetpan/libetpan.h&gt;
13446
13447int mailmessage_fetch_header(mailmessage * msg_info,
13448 char ** result,
13449 size_t * result_len);
13450 </programlisting>
13451
13452 <para>
13453 This function returns the header of the message as a string.
13454 </para>
13455
13456 </sect2>
13457
13458 <sect2 id="mailmessage-fetch-body">
13459 <title>mailmessage_fetch_body</title>
13460
13461 <programlisting role="C">
13462#include &lt;libetpan/libetpan.h&gt;
13463
13464int mailmessage_fetch_body(mailmessage * msg_info,
13465 char ** result, size_t * result_len);
13466 </programlisting>
13467
13468 <para>
13469 This function returns the content of the message (without
13470 headers).
13471 </para>
13472 </sect2>
13473
13474 <sect2 id="mailmessage-fetch-size">
13475 <title>mailmessage_fetch_size</title>
13476
13477 <programlisting role="C">
13478#include &lt;libetpan/libetpan.h&gt;
13479
13480int mailmessage_fetch_size(mailmessage * msg_info,
13481 size_t * result);
13482 </programlisting>
13483
13484 <para>
13485 This function returns the size of the message content.
13486 </para>
13487 </sect2>
13488
13489 <sect2 id="mailmessage-get-bodystructure">
13490 <title>mailmessage_get_bodystructure</title>
13491
13492 <programlisting role="C">
13493#include &lt;libetpan/libetpan.h&gt;
13494
13495int mailmessage_get_bodystructure(mailmessage * msg_info,
13496 struct mailmime ** result);
13497 </programlisting>
13498
13499 <para>
13500 This functions returns the MIME structure of the message.
13501 The returned information <emphasis>MUST</emphasis> not be
13502 freed by hand. It is freed by
13503 <command>mailmessage_flush()</command> or
13504 <command>mailmessage_free()</command>
13505 (see <xref linkend="mailmime">).
13506 </para>
13507 </sect2>
13508
13509 <sect2 id="mailmessage-fetch-section">
13510 <title>mailmessage_fetch_section</title>
13511
13512 <programlisting role="C">
13513#include &lt;libetpan/libetpan.h&gt;
13514
13515int mailmessage_fetch_section(mailmessage * msg_info,
13516 struct mailmime * mime,
13517 char ** result, size_t * result_len);
13518 </programlisting>
13519
13520 <para>
13521 This function returns the content of a MIME part.
13522 </para>
13523 </sect2>
13524
13525 <sect2 id="mailmessage-fetch-section-header">
13526 <title>mailmessage_fetch_section_header</title>
13527
13528 <programlisting role="C">
13529#include &lt;libetpan/libetpan.h&gt;
13530
13531int mailmessage_fetch_section_header(mailmessage * msg_info,
13532 struct mailmime * mime,
13533 char ** result,
13534 size_t * result_len);
13535 </programlisting>
13536
13537 <para>
13538 This function returns the header of the message contained
13539 in the given MIME part.
13540 </para>
13541 </sect2>
13542
13543 <sect2 id="mailmessage-fetch-section-mime">
13544 <title>mailmessage_fetch_section_mime</title>
13545
13546 <programlisting role="C">
13547#include &lt;libetpan/libetpan.h&gt;
13548
13549int mailmessage_fetch_section_mime(mailmessage * msg_info,
13550 struct mailmime * mime,
13551 char ** result,
13552 size_t * result_len);
13553 </programlisting>
13554
13555 <para>
13556 This function returns the MIME header of the given MIME
13557 part.
13558 </para>
13559 </sect2>
13560
13561 <sect2 id="mailmessage-fetch-section-body">
13562 <title>mailmessage_fetch_section_body</title>
13563
13564 <programlisting role="C">
13565#include &lt;libetpan/libetpan.h&gt;
13566
13567int mailmessage_fetch_section_body(mailmessage * msg_info,
13568 struct mailmime * mime,
13569 char ** result,
13570 size_t * result_len);
13571 </programlisting>
13572
13573 <para>
13574 This function returns the text part of the message contained
13575 in the given MIME part.
13576 </para>
13577 </sect2>
13578
13579 <sect2 id="mailmessage-fetch-envelope">
13580 <title>mailmessage_fetch_envelope</title>
13581
13582 <programlisting role="C">
13583#include &lt;libetpan/libetpan.h&gt;
13584
13585int mailmessage_fetch_envelope(mailmessage * msg_info,
13586 struct mailimf_fields ** result);
13587 </programlisting>
13588 </sect2>
13589
13590 <sect2 id="mailmessage-get-flags">
13591 <title>mailmessage_get_flags</title>
13592
13593 <programlisting role="C">
13594#include &lt;libetpan/libetpan.h&gt;
13595
13596int mailmessage_get_flags(mailmessage * msg_info,
13597 struct mail_flags ** result);
13598 </programlisting>
13599
13600 <para>
13601 This function returns the flags related to the message.
13602 The returned information MUST not be freed by hand. It is freed by
13603 <command>mailmessage_free()</command>.
13604 </para>
13605 </sect2>
13606
13607 <sect2 id="mailmessage-resolve-single-fields">
13608 <title>mailmessage_resolve_single_fields</title>
13609
13610 <programlisting role="C">
13611#include &lt;libetpan/libetpan.h&gt;
13612
13613void mailmessage_resolve_single_fields(mailmessage * msg_info);
13614 </programlisting>
13615
13616 <para>
13617 This function will use the fields information to fill
13618 the single_fields structure in the mailmessage structure.
13619 </para>
13620 </sect2>
13621
13622 <sect2 id="mailmessage-list">
13623 <title>Message list</title>
13624
13625 <programlisting role="C">
13626#include &lt;libetpan/libetpan.h&gt;
13627
13628struct mailmessage_list {
13629 carray * msg_tab; /* elements are (mailmessage *) */
13630};
13631
13632struct mailmessage_list * mailmessage_list_new(carray * msg_tab);
13633
13634void mailmessage_list_free(struct mailmessage_list * env_list);
13635 </programlisting>
13636
13637 <para>
13638 This is a list of messages.
13639 </para>
13640
13641 <para>
13642 <command>msg_tab</command> is an array containing the
13643 messages (see linkend="carray").
13644 </para>
13645
13646 <para>
13647 <command>mailmessage_list_new()</command> will initialize a
13648 list of messages, using a given array of messages.
13649 </para>
13650
13651 <para>
13652 <command>mailmessage_list_free()</command> will free the
13653 memory used by the list of messages. This will also free the
13654 messages.
13655 </para>
13656 </sect2>
13657
13658 <sect2 id="mailmessage-tree">
13659 <title>Message tree</title>
13660
13661 <programlisting role="C">
13662#include &lt;libetpan/libetpan.h&gt;
13663
13664struct mailmessage_tree {
13665 struct mailmessage_tree * node_parent;
13666 char * node_msgid;
13667 time_t node_date;
13668 mailmessage * node_msg;
13669 carray * node_children; /* array of (struct mailmessage_tree *) */
13670
13671 /* private, used for threading */
13672 int node_is_reply;
13673 char * node_base_subject;
13674};
13675
13676
13677struct mailmessage_tree *
13678mailmessage_tree_new(char * node_msgid, time_t node_date,
13679 mailmessage * node_msg);
13680
13681void mailmessage_tree_free(struct mailmessage_tree * tree);
13682
13683void mailmessage_tree_free_recursive(struct mailmessage_tree * tree);
13684 </programlisting>
13685
13686 <para>
13687 This is a node of a tree of messages.
13688 </para>
13689
13690 <itemizedlist>
13691 <listitem>
13692 <para>
13693 <command>node_parent</command> is the parent of this
13694 node.
13695 </para>
13696 </listitem>
13697
13698 <listitem>
13699 <para>
13700 <command>node_msgid</command> is the content of the
13701 field <command>Message-ID</command> of the message.
13702 </para>
13703 </listitem>
13704
13705 <listitem>
13706 <para>
13707 <command>node_date</command> is the date in UNIX
13708 format.
13709 </para>
13710 </listitem>
13711
13712 <listitem>
13713 <para>
13714 <command>node_msg</command> is the message of the node.
13715 The message should have the <command>msg_fields</command>
13716 field initialized.
13717 </para>
13718 </listitem>
13719
13720 <listitem>
13721 <para>
13722 <command>node_children</command> is the list of
13723 children of this node.
13724 </para>
13725 </listitem>
13726
13727 <listitem>
13728 <para>
13729 <command>node_is_reply</command> is set to 1 if the
13730 message is a reply.
13731 </para>
13732 </listitem>
13733
13734 <listitem>
13735 <para>
13736 <command>node_base_subject</command> is the base subject
13737 of the message (base subject is defined in definition of
13738 IMAP thread draft).
13739 </para>
13740 </listitem>
13741 </itemizedlist>
13742
13743 <para>
13744 <command>mailmessage_tree_new()</command> will initialize a
13745 message node.
13746 </para>
13747
13748 <para>
13749 <command>mailmessage_tree_free()</command> will release
13750 memory used by the node. This will <emphasis>NOT</emphasis>
13751 free the message.
13752 </para>
13753 </sect2>
13754
13755 <sect2 id="mail-flags">
13756 <title>Message flags</title>
13757
13758 <programlisting role="C">
13759#include &lt;libetpan/libetpan.h&gt;
13760
13761enum {
13762 MAIL_FLAG_NEW = 1 &lt;&lt; 0,
13763 MAIL_FLAG_SEEN = 1 &lt;&lt; 1,
13764 MAIL_FLAG_FLAGGED = 1 &lt;&lt; 2,
13765 MAIL_FLAG_DELETED = 1 &lt;&lt; 3,
13766 MAIL_FLAG_ANSWERED = 1 &lt;&lt; 4,
13767 MAIL_FLAG_FORWARDED = 1 &lt;&lt; 5,
13768 MAIL_FLAG_CANCELLED = 1 &lt;&lt; 6,
13769};
13770
13771struct mail_flags {
13772 uint32_t fl_flags;
13773 clist * fl_extension; /* elements are (char *) */
13774};
13775
13776struct mail_flags * mail_flags_new(uint32_t fl_flags, clist * fl_ext);
13777
13778void mail_flags_free(struct mail_flags * flags);
13779
13780int mail_flags_add_extension(struct mail_flags * flags,
13781 char * ext_flag);
13782
13783int mail_flags_remove_extension(struct mail_flags * flags,
13784 char * ext_flag);
13785
13786int mail_flags_has_extension(struct mail_flags * flags,
13787 char * ext_flag);
13788 </programlisting>
13789
13790 <para>
13791 This is the structure containing the message flags.
13792 </para>
13793
13794 <itemizedlist>
13795 <listitem>
13796 <para>
13797 <command>fl_flags</command> will contain the standards
13798 flags. The value will be a combinaison (with or binary
13799 operation) of <command>MAIL_FLAG_XXX</command> values.
13800 </para>
13801 </listitem>
13802 <listitem>
13803 <para>
13804 <command>fl_extension</command> will be a list (see
13805 <xref linkend="clist">) of strings representing the
13806 non-standard flags.
13807 </para>
13808 </listitem>
13809 </itemizedlist>
13810 </sect2>
13811
13812 <sect2>
13813 <title>Example</title>
13814
13815 <example>
13816 <title>use of message</title>
13817
13818 <programlisting role="C">
13819#include &lt;libetpan/libetpan.h&gt;
13820
13821#define DEST_CHARSET "iso-8859-1"
13822
13823enum {
13824 NO_ERROR,
13825 ERROR_FILE,
13826 ERROR_MEMORY,
13827 ERROR_INVAL,
13828 ERROR_FETCH,
13829};
13830
13831/* returns TRUE is given MIME part is a text part */
13832
13833int etpan_mime_is_text(struct mailmime * build_info)
13834{
13835 if (build_info-&gt;mm_type == MAILMIME_SINGLE) {
13836 if (build_info-&gt;mm_content_type != NULL) {
13837 if (build_info-&gt;mm_content_type-&gt;ct_type-&gt;tp_type ==
13838 MAILMIME_TYPE_DISCRETE_TYPE) {
13839 if (build_info-&gt;mm_content_type-&gt;ct_type-&gt;tp_data.tp_discrete_type-&gt;dt_type ==
13840 MAILMIME_DISCRETE_TYPE_TEXT)
13841 return 1;
13842 }
13843 }
13844 else
13845 return 1;
13846 }
13847
13848 return 0;
13849}
13850
13851
13852/* display content type */
13853
13854int show_part_info(FILE * f,
13855 struct mailmime_single_fields * mime_fields,
13856 struct mailmime_content * content)
13857{
13858 char * description;
13859 char * filename;
13860 int col;
13861 int r;
13862
13863 description = mime_fields-&gt;fld_description;
13864 filename = mime_fields-&gt;fld_disposition_filename;
13865
13866 col = 0;
13867
13868 r = fprintf(f, " [ Part ");
13869 if (r &lt; 0)
13870 goto err;
13871
13872 if (content != NULL) {
13873 r = mailmime_content_type_write(f, &amp;col, content);
13874 if (r != MAILIMF_NO_ERROR)
13875 goto err;
13876 }
13877
13878 if (filename != NULL) {
13879 r = fprintf(f, " (%s)", filename);
13880 if (r &lt; 0)
13881 goto err;
13882 }
13883
13884 if (description != NULL) {
13885 r = fprintf(f, " : %s", description);
13886 if (r &lt; 0)
13887 goto err;
13888 }
13889
13890 r = fprintf(f, " ]\n\n");
13891 if (r &lt; 0)
13892 goto err;
13893
13894 return NO_ERROR;
13895
13896 err:
13897 return ERROR_FILE;
13898}
13899
13900/* fetch message and decode if it is base64 or quoted-printable */
13901
13902int etpan_fetch_message(mailmessage * msg_info,
13903 struct mailmime * mime_part,
13904 struct mailmime_single_fields * fields,
13905 char ** result, size_t * result_len)
13906{
13907 char * data;
13908 size_t len;
13909 int r;
13910 int encoding;
13911 char * decoded;
13912 size_t decoded_len;
13913 size_t cur_token;
13914 int res;
13915 int encoded;
13916
13917 encoded = 0;
13918
13919 r = mailmessage_fetch_section(msg_info,
13920 mime_part, &amp;data, &amp;len);
13921 if (r != MAIL_NO_ERROR) {
13922 res = ERROR_FETCH;
13923 goto err;
13924 }
13925
13926 encoded = 1;
13927
13928 /* decode message */
13929
13930 if (encoded) {
13931 if (fields-&gt;fld_encoding != NULL)
13932 encoding = fields-&gt;fld_encoding-&gt;enc_type;
13933 else
13934 encoding = MAILMIME_MECHANISM_8BIT;
13935 }
13936 else {
13937 encoding = MAILMIME_MECHANISM_8BIT;
13938 }
13939
13940 cur_token = 0;
13941 r = mailmime_part_parse(data, len, &amp;cur_token,
13942 encoding, &amp;decoded, &amp;decoded_len);
13943 if (r != MAILIMF_NO_ERROR) {
13944 res = ERROR_FETCH;
13945 goto free;
13946 }
13947
13948 mailmessage_fetch_result_free(msg_info, data);
13949
13950 * result = decoded;
13951 * result_len = decoded_len;
13952
13953 return NO_ERROR;
13954
13955 free:
13956 mailmessage_fetch_result_free(msg_info, data);
13957 err:
13958 return res;
13959}
13960
13961/* fetch fields */
13962
13963struct mailimf_fields * fetch_fields(mailmessage * msg_info,
13964 struct mailmime * mime)
13965{
13966 char * data;
13967 size_t len;
13968 int r;
13969 size_t cur_token;
13970 struct mailimf_fields * fields;
13971
13972 r = mailmessage_fetch_section_header(msg_info, mime,
13973 &amp;data, &amp;len);
13974 if (r != MAIL_NO_ERROR)
13975 return NULL;
13976
13977 cur_token = 0;
13978 r = mailimf_envelopes_fields_parse(data, len,
13979 &amp;cur_token, &amp;fields);
13980 if (r != MAILIMF_NO_ERROR) {
13981 mailmessage_fetch_result_free(msg_info, data);
13982 return NULL;
13983 }
13984
13985 mailmessage_fetch_result_free(msg_info, data);
13986
13987 return fields;
13988}
13989
13990/* render message */
13991
13992static int etpan_render_mime(FILE * f, mailmessage * msg_info,
13993 struct mailmime * mime)
13994{
13995 int r;
13996 clistiter * cur;
13997 int col;
13998 int text;
13999 int show;
14000 struct mailmime_single_fields fields;
14001 int res;
14002
14003 mailmime_single_fields_init(&amp;fields, mime-&gt;mm_mime_fields,
14004 mime-&gt;mm_content_type);
14005
14006 text = etpan_mime_is_text(mime);
14007
14008 r = show_part_info(f, &amp;fields, mime-&gt;mm_content_type);
14009 if (r != NO_ERROR) {
14010 res = r;
14011 goto err;
14012 }
14013
14014 switch(mime-&gt;mm_type) {
14015 case MAILMIME_SINGLE:
14016 show = 0;
14017 if (text)
14018 show = 1;
14019
14020 if (show) {
14021 char * data;
14022 size_t len;
14023 char * converted;
14024 size_t converted_len;
14025 char * source_charset;
14026 size_t write_len;
14027
14028 /* viewable part */
14029
14030 r = etpan_fetch_message(msg_info, mime,
14031 &amp;fields, &amp;data, &amp;len);
14032 if (r != NO_ERROR) {
14033 res = r;
14034 goto err;
14035 }
14036
14037 source_charset = fields.fld_content_charset;
14038 if (source_charset == NULL)
14039 source_charset = DEST_CHARSET;
14040
14041 r = charconv_buffer(source_charset, DEST_CHARSET,
14042 data, len, &amp;converted, &amp;converted_len);
14043 if (r != MAIL_CHARCONV_NO_ERROR) {
14044
14045 r = fprintf(f, "[ error converting charset from %s to %s ]\n",
14046 source_charset, DEST_CHARSET);
14047 if (r &lt; 0) {
14048 res = ERROR_FILE;
14049 goto err;
14050 }
14051
14052 write_len = fwrite(data, 1, len, f);
14053 if (write_len != len) {
14054 mailmime_decoded_part_free(data);
14055 res = r;
14056 goto err;
14057 }
14058 }
14059 else {
14060 write_len = fwrite(converted, 1, converted_len, f);
14061 if (write_len != len) {
14062 charconv_buffer_free(converted);
14063 mailmime_decoded_part_free(data);
14064 res = r;
14065 goto err;
14066 }
14067
14068 charconv_buffer_free(converted);
14069 }
14070
14071 write_len = fwrite("\r\n\r\n", 1, 4, f);
14072 if (write_len &lt; 4) {
14073 mailmime_decoded_part_free(data);
14074 res = ERROR_FILE;
14075 goto err;
14076 }
14077
14078 mailmime_decoded_part_free(data);
14079 }
14080 else {
14081 /* not viewable part */
14082
14083 r = fprintf(f, " (not shown)\n\n");
14084 if (r &lt; 0) {
14085 res = ERROR_FILE;
14086 goto err;
14087 }
14088 }
14089
14090 break;
14091
14092 case MAILMIME_MULTIPLE:
14093
14094 if (strcasecmp(mime-&gt;mm_content_type-&gt;ct_subtype,
14095 "alternative") == 0) {
14096 struct mailmime * prefered_body;
14097 int prefered_score;
14098
14099 /* case of multiple/alternative */
14100
14101 /*
14102 we choose the better part,
14103 alternative preference :
14104
14105 text/plain =&gt; score 3
14106 text/xxx =&gt; score 2
14107 other =&gt; score 1
14108 */
14109
14110 prefered_body = NULL;
14111 prefered_score = 0;
14112
14113 for(cur = clist_begin(mime-&gt;mm_data.mm_multipart.mm_mp_list) ;
14114 cur != NULL ; cur = clist_next(cur)) {
14115 struct mailmime * submime;
14116 int score;
14117
14118 score = 1;
14119 submime = clist_content(cur);
14120 if (etpan_mime_is_text(submime))
14121 score = 2;
14122
14123 if (submime-&gt;mm_content_type != NULL) {
14124 if (strcasecmp(submime-&gt;mm_content_type-&gt;ct_subtype,
14125 "plain") == 0)
14126 score = 3;
14127 }
14128
14129 if (score &gt; prefered_score) {
14130 prefered_score = score;
14131 prefered_body = submime;
14132 }
14133 }
14134
14135 if (prefered_body != NULL) {
14136 r = etpan_render_mime(f, msg_info, prefered_body);
14137 if (r != NO_ERROR) {
14138 res = r;
14139 goto err;
14140 }
14141 }
14142 }
14143 else {
14144 for(cur = clist_begin(mime-&gt;mm_data.mm_multipart.mm_mp_list) ;
14145 cur != NULL ; cur = clist_next(cur)) {
14146
14147 r = etpan_render_mime(f, msg_info, clist_content(cur));
14148 if (r != NO_ERROR) {
14149 res = r;
14150 goto err;
14151 }
14152 }
14153 }
14154
14155 break;
14156
14157 case MAILMIME_MESSAGE:
14158
14159 if (mime-&gt;mm_data.mm_message.mm_fields != NULL) {
14160 struct mailimf_fields * fields;
14161
14162 if (msg_info != NULL) {
14163 fields = fetch_fields(msg_info, mime);
14164 if (fields == NULL) {
14165 res = ERROR_FETCH;
14166 goto err;
14167 }
14168
14169 col = 0;
14170 r = mailimf_fields_write(f, &amp;col, fields);
14171 if (r != NO_ERROR) {
14172 mailimf_fields_free(fields);
14173 res = r;
14174 goto err;
14175 }
14176
14177 mailimf_fields_free(fields);
14178 }
14179 else {
14180 col = 0;
14181 r = fields_write(f, &amp;col, mime-&gt;mm_data.mm_message.mm_fields);
14182 if (r != NO_ERROR) {
14183 res = r;
14184 goto err;
14185 }
14186 }
14187
14188 r = fprintf(f, "\r\n");
14189 if (r &lt; 0) {
14190 res = ERROR_FILE;
14191 goto err;
14192 }
14193 }
14194
14195 if (mime-&gt;mm_data.mm_message.mm_msg_mime != NULL) {
14196 r = etpan_render_mime(f, msg_info,
14197 mime-&gt;mm_data.mm_message.mm_msg_mime);
14198 if (r != NO_ERROR) {
14199 res = r;
14200 goto err;
14201 }
14202 }
14203
14204 break;
14205 }
14206
14207 return NO_ERROR;
14208
14209 err:
14210 return res;
14211}
14212
14213
14214
14215int main(void)
14216{
14217 struct mailstorage * storage;
14218 int r;
14219
14220 storage = mailstorage_new(NULL);
14221
14222 imap_mailstorage_init(storage, "imap.my-servers.org", 0,
14223 NULL, CONNECTION_TYPE_TRY_STARTTLS, IMAP_AUTH_TYPE_PLAIN,
14224 "my-login", "my-password", 1, "/home/login/.libetpan/cache");
14225
14226 r = mailstorage_connect(storage);
14227 if (r == MAIL_NO_ERROR) {
14228 struct mailfolder * folder;
14229
14230 folder = mailfolder_new(storage, "INBOX", NULL);
14231
14232 r = mailfolder_connect(folder);
14233 if (r == MAIL_NO_ERROR) {
14234 struct mailmessage_list * msg_list;
14235 mailmessage * msg;
14236
14237 mailfolder_get_messages_list(folder, &amp;msg_list);
14238
14239 if (carray_count(msg_list-&gt;msg_tab) &gt; 0) {
14240 struct mailmime * mime;
14241
14242 msg = carray_get(msg_list-&gt;msg_tab, 0);
14243
14244 mailmessage_get_bodystructure(msg, &amp;mime);
14245
14246 recursive_fetch(msg, mime);
14247
14248 /* do the things */
14249
14250 mailmessage_flush(msg);
14251 }
14252 mailmessage_list_free(msg_list);
14253
14254 mailfolder_disconnect(folder);
14255 }
14256
14257 mailstorage_disconnect(storage);
14258 }
14259
14260 mailstorage_free(storage);
14261}
14262 </programlisting>
14263 </example>
14264 </sect2>
14265 </sect1>
14266
14267 <!-- Session -->
14268 <sect1>
14269 <title>Session</title>
14270
14271 <sect2 id="mailsession-driver">
14272 <title>Session driver</title>
14273
14274 <programlisting role="C">
14275#include &lt;libetpan/libetpan.h&gt;
14276
14277struct mailsession_driver {
14278 char * sess_name;
14279
14280 int (* sess_initialize)(mailsession * session);
14281 void (* sess_uninitialize)(mailsession * session);
14282
14283 int (* sess_parameters)(mailsession * session,
14284 int id, void * value);
14285
14286 int (* sess_connect_stream)(mailsession * session, mailstream * s);
14287 int (* sess_connect_path)(mailsession * session, char * path);
14288
14289 int (* sess_starttls)(mailsession * session);
14290
14291 int (* sess_login)(mailsession * session, char * userid, char * password);
14292 int (* sess_logout)(mailsession * session);
14293 int (* sess_noop)(mailsession * session);
14294
14295 /* folders operations */
14296
14297 int (* sess_build_folder_name)(mailsession * session, char * mb,
14298 char * name, char ** result);
14299
14300 int (* sess_create_folder)(mailsession * session, char * mb);
14301 int (* sess_delete_folder)(mailsession * session, char * mb);
14302 int (* sess_rename_folder)(mailsession * session, char * mb,
14303 char * new_name);
14304 int (* sess_check_folder)(mailsession * session);
14305 int (* sess_examine_folder)(mailsession * session, char * mb);
14306 int (* sess_select_folder)(mailsession * session, char * mb);
14307 int (* sess_expunge_folder)(mailsession * session);
14308 int (* sess_status_folder)(mailsession * session, char * mb,
14309 uint32_t * result_num, uint32_t * result_recent,
14310 uint32_t * result_unseen);
14311 int (* sess_messages_number)(mailsession * session, char * mb,
14312 uint32_t * result);
14313 int (* sess_recent_number)(mailsession * session, char * mb,
14314 uint32_t * result);
14315 int (* sess_unseen_number)(mailsession * session, char * mb,
14316 uint32_t * result);
14317
14318 int (* sess_list_folders)(mailsession * session, char * mb,
14319 struct mail_list ** result);
14320 int (* sess_lsub_folders)(mailsession * session, char * mb,
14321 struct mail_list ** result);
14322
14323 int (* sess_subscribe_folder)(mailsession * session, char * mb);
14324 int (* sess_unsubscribe_folder)(mailsession * session, char * mb);
14325
14326 /* messages operations */
14327
14328 int (* sess_append_message)(mailsession * session,
14329 char * message, size_t size);
14330 int (* sess_copy_message)(mailsession * session,
14331 uint32_t num, char * mb);
14332 int (* sess_move_message)(mailsession * session,
14333 uint32_t num, char * mb);
14334
14335 int (* sess_get_message)(mailsession * session,
14336 uint32_t num, mailmessage ** result);
14337
14338 int (* sess_get_message_by_uid)(mailsession * session,
14339 const char * uid, mailmessage ** result);
14340
14341 int (* sess_get_messages_list)(mailsession * session,
14342 struct mailmessage_list ** result);
14343 int (* sess_get_envelopes_list)(mailsession * session,
14344 struct mailmessage_list * env_list);
14345 int (* sess_remove_message)(mailsession * session, uint32_t num);
14346};
14347 </programlisting>
14348
14349 <para>
14350 This is a driver for a session.
14351 </para>
14352
14353 <itemizedlist>
14354 <listitem>
14355 <para>
14356 <command>sess_name</command> is the name of the driver.
14357 </para>
14358 </listitem>
14359
14360 <listitem>
14361 <para>
14362 <command>sess_initialize()</command> is the function
14363 that will initializes a data structure (field
14364 <command>sess_data</command> in the session) specific to
14365 the driver.
14366 The field data (field <command>sess_data</command> in
14367 the session) is the state of the session,
14368 the internal data structure used by the driver.
14369 It is called when creating the
14370 <command>mailsession</command> structure with
14371 <command>mailsession_new()</command>.
14372 </para>
14373 </listitem>
14374
14375 <listitem>
14376 <para>
14377 <command>sess_uninitialize()</command> frees the structure
14378 created with <command>sess_initialize()</command>
14379 </para>
14380 </listitem>
14381
14382 <listitem>
14383 <para>
14384 <command>sess_parameters()</command> implements
14385 functions specific to the given mail access.
14386 </para>
14387 </listitem>
14388
14389 <listitem>
14390 <para>
14391 <command>sess_connect_stream()</command> connects a
14392 stream to the session.
14393 </para>
14394 </listitem>
14395
14396 <listitem>
14397 <para>
14398 <command>sess_connect_path()</command> notify a main
14399 path to the session.
14400 </para>
14401 </listitem>
14402
14403 <listitem>
14404 <para>
14405 <command>sess_starttls()</command> changes the current
14406 stream to a TLS stream
14407 (see <xref linkend="mailstream-ssl">).
14408 </para>
14409 </listitem>
14410
14411 <listitem>
14412 <para>
14413 <command>sess_login()</command> notifies the user and
14414 the password to authenticate to the session.
14415 </para>
14416 </listitem>
14417
14418 <listitem>
14419 <para>
14420 <command>sess_logout()</command> exits the session and
14421 closes the stream.
14422 </para>
14423 </listitem>
14424
14425 <listitem>
14426 <para>
14427 <command>sess_noop()</command> does no operation on the
14428 session, but it can be used to poll for the status of
14429 the connection.
14430 </para>
14431 </listitem>
14432
14433 <listitem>
14434 <para>
14435 <command>sess_build_folder_name()</command> will return an
14436 allocated string with that contains the complete path of
14437 the folder to create.
14438 <emphasis>Use of this method is deprecated</emphasis>.
14439 </para>
14440 </listitem>
14441
14442 <listitem>
14443 <para>
14444 <command>sess_create_folder()</command> creates the
14445 folder that corresponds to the given name.
14446 <emphasis>Use of this method is deprecated</emphasis>.
14447 </para>
14448 </listitem>
14449
14450 <listitem>
14451 <para>
14452 <command>sess_delete_folder()</command> deletes the folder
14453 that corresponds to the given name.
14454 <emphasis>Use of this method is deprecated</emphasis>.
14455 </para>
14456 </listitem>
14457
14458 <listitem>
14459 <para>
14460 <command>sess_rename_folder()</command> change the name
14461 of the folder.
14462 <emphasis>Use of this method is deprecated</emphasis>.
14463 </para>
14464 </listitem>
14465
14466 <listitem>
14467 <para>
14468 <command>sess_check_folder()</command> makes a
14469 checkpoint of the session.
14470 </para>
14471 </listitem>
14472
14473 <listitem>
14474 <para>
14475 <command>sess_examine_folder()</command> selects a mailbox as
14476 readonly.
14477 <emphasis>Use of this method is deprecated</emphasis>.
14478 </para>
14479 </listitem>
14480
14481 <listitem>
14482 <para>
14483 <command>sess_select_folder()</command> selects a mailbox.
14484 </para>
14485 </listitem>
14486
14487 <listitem>
14488 <para>
14489 <command>sess_expunge_folder()</command> deletes all
14490 messages marked \Deleted.
14491 </para>
14492 </listitem>
14493
14494 <listitem>
14495 <para>
14496 <command>sess_status_folder()</command> queries the
14497 status of the folder (number of messages, number of
14498 recent messages, number of unseen messages).
14499 </para>
14500 </listitem>
14501
14502 <listitem>
14503 <para>
14504 <command>sess_messages_number()</command> queries the
14505 number of messages in the folder.
14506 </para>
14507 </listitem>
14508
14509 <listitem>
14510 <para>
14511 <command>sess_recent_number()</command> queries the
14512 number of recent messages in the folder.
14513 </para>
14514 </listitem>
14515
14516 <listitem>
14517 <para>
14518 <command>sess_unseen_number()</command> queries the number of
14519 unseen messages in the folder.
14520 </para>
14521 </listitem>
14522
14523 <listitem>
14524 <para>
14525 <command>sess_list_folders()</command> returns the list of
14526 all sub-mailboxes of the given mailbox.
14527 <emphasis>Use of this method is deprecated</emphasis>.
14528 </para>
14529 </listitem>
14530
14531 <listitem>
14532 <para>
14533 <command>sess_lsub_folders()</command> returns the list of
14534 subscribed sub-mailboxes of the given mailbox.
14535 <emphasis>Use of this method is deprecated</emphasis>.
14536 </para>
14537 </listitem>
14538
14539 <listitem>
14540 <para>
14541 <command>sess_subscribe_folder()</command> subscribes to
14542 the given mailbox.
14543 <emphasis>Use of this method is deprecated</emphasis>.
14544 </para>
14545 </listitem>
14546
14547 <listitem>
14548 <para>
14549 <command>sess_unsubscribe_folder()</command> unsubscribes to
14550 the given mailbox.
14551 <emphasis>Use of this method is deprecated</emphasis>.
14552 </para>
14553 </listitem>
14554
14555 <listitem>
14556 <para>
14557 <command>sess_append_message()</command> adds a RFC 2822
14558 message to the current given mailbox.
14559 </para>
14560 </listitem>
14561
14562 <listitem>
14563 <para>
14564 <command>sess_copy_message()</command> copies a message
14565 whose number is given to a given mailbox. The mailbox
14566 must be accessible from the same session.
14567 <emphasis>Use of this method is deprecated</emphasis>.
14568 </listitem>
14569
14570 <listitem>
14571 <para>
14572 <command>sess_move_message()</command> moves a message whose
14573 number is given to
14574 a given mailbox. The mailbox must be accessible from the
14575 same session.
14576 <emphasis>Use of this method is deprecated</emphasis>.
14577 </para>
14578 </listitem>
14579
14580 <listitem>
14581 <para>
14582 <command>sess_get_messages_list()</command> returns the list
14583 of message numbers
14584 of the current mailbox
14585 (see <xref linkend="mailmessage-list">).
14586 </para>
14587 </listitem>
14588
14589 <listitem>
14590 <para>
14591 <command>sess_get_envelopes_list()</command> fills the parsed
14592 fields in the <command>mailmessage</command> structures
14593 (see <xref linkend="mailmessage">)
14594 of the <command>mailmessage_list</command>
14595 (see <xref linkend="mailmessage-list">).
14596 </para>
14597 </listitem>
14598
14599 <listitem>
14600 <para>
14601 <command>sess_remove_message()</command> removes the given
14602 message from the mailbox.
14603 The message is permanently deleted.
14604 <emphasis>Use of this method is deprecated</emphasis>.
14605 </para>
14606 </listitem>
14607
14608 <listitem>
14609 <para>
14610 <command>sess_get_message()</command> returns a
14611 mailmessage structure
14612 (see <xref linkend="mailmessage">)
14613 that corresponds
14614 to the given message number.
14615 <emphasis>Use of this method is deprecated</emphasis>.
14616 </para>
14617 </listitem>
14618
14619 <listitem>
14620 <para>
14621 <command>sess_get_message_by_uid()</command> returns a
14622 mailmessage structure
14623 (see <xref linkend="mailmessage">)
14624 that corresponds
14625 to the given message unique identifier.
14626 </para>
14627 </listitem>
14628 </itemizedlist>
14629
14630 <para>
14631 mandatory functions are the following :
14632 </para>
14633
14634 <itemizedlist>
14635 <listitem>
14636 <para>
14637 <command>sess_connect_stream()</command> or
14638 <command>connect_path()</command>
14639 </para>
14640 </listitem>
14641
14642 <listitem>
14643 <para>
14644 <command>sess_logout()</command>
14645 </para>
14646 </listitem>
14647
14648 <listitem>
14649 <para>
14650 <command>sess_get_messages_list()</command>
14651 </para>
14652 </listitem>
14653
14654 <listitem>
14655 <para>
14656 <command>sess_get_envelopes_list()</command>
14657 </para>
14658 </listitem>
14659 </itemizedlist>
14660
14661 <para>
14662 we advise you to implement these functions :
14663 </para>
14664
14665 <itemizedlist>
14666 <listitem>
14667 <para>
14668 <command>sess_select_folder()</command> (in case a session
14669 can access several folders).
14670 </para>
14671 </listitem>
14672
14673 <listitem>
14674 <para>
14675 <command>sess_noop()</command> (to check if the server is
14676 responding)
14677 </para>
14678 </listitem>
14679
14680 <listitem>
14681 <para>
14682 <command>sess_check_folder()</command> (to make a checkpoint
14683 of the session)
14684 </para>
14685 </listitem>
14686
14687 <listitem>
14688 <para>
14689 <command>sess_status_folder()</command>,
14690 <command>sess_messages_number()</command>,
14691 <command>sess_recent_number()</command>,
14692 <command>sess_unseen_number()</command>
14693 (to get stat of the folder)
14694 </para>
14695 </listitem>
14696
14697 <listitem>
14698 <para>
14699 <command>sess_append_message()</command> (but can't be done
14700 in the case of POP3 at least).
14701 </para>
14702 </listitem>
14703
14704 <listitem>
14705 <para>
14706 <command>sess_login()</command> in a case of an
14707 authenticated driver.
14708 </para>
14709 </listitem>
14710
14711 <listitem>
14712 <para>
14713 <command>sess_starttls()</command> in a case of a stream
14714 driver, if the procotol supports STARTTLS.
14715 </para>
14716 </listitem>
14717
14718 <listitem>
14719 <para>
14720 <command>sess_get_message_by_uid()</command> so that the
14721 application can remember the messages
14722 by UID and build its own list of messages.
14723 </para>
14724 </listitem>
14725
14726 <listitem>
14727 <para>
14728 Everything that is specific to the driver will be
14729 implemented in <command>sess_parameters()</command>.
14730 </para>
14731 </listitem>
14732 </itemizedlist>
14733 </sect2>
14734
14735 <sect2 id="mailsession">
14736 <title>Session</title>
14737
14738 <programlisting role="C">
14739#include &lt;libetpan/libetpan.h&gt;
14740
14741struct mailsession {
14742 void * sess_data;
14743 mailsession_driver * sess_driver;
14744};
14745
14746mailsession * mailsession_new(mailsession_driver * sess_driver);
14747
14748void mailsession_free(mailsession * session);
14749 </programlisting>
14750
14751 <para>
14752 This is a session. This is an abstraction used to access the
14753 storage, using the network or the filesystem.
14754 </para>
14755
14756 <itemizedlist>
14757 <listitem>
14758 <para>
14759 <command>sess_data</command> is the state of the
14760 session. This is specific to the driver.
14761 </para>
14762 </listitem>
14763 <listitem>
14764 <para>
14765 <command>sess_driver</command> is the driver of the
14766 session.
14767 </para>
14768 </listitem>
14769 </itemizedlist>
14770
14771 <para>
14772 <command>mailsession_new()</command> will create a new session
14773 using the given driver (<command>sess_driver</command>).
14774 </para>
14775
14776 <para>
14777 <command>mailsession_free()</command> will release the memory
14778 used by the session.
14779 </para>
14780 </sect2>
14781
14782 <sect2>
14783 <title>mailsession_parameters</title>
14784
14785 <programlisting>
14786#include &lt;libetpan/libetpan.h&gt;
14787
14788int mailsession_parameters(mailsession * session,
14789 int id, void * value);
14790 </programlisting>
14791
14792 <para>
14793 This function make calls specific to the driver
14794 </para>
14795 </sect2>
14796
14797 <sect2>
14798 <title>mailsession_connect_stream</title>
14799
14800 <programlisting>
14801#include &lt;libetpan/libetpan.h&gt;
14802
14803int mailsession_connect_stream(mailsession * session, mailstream * s);
14804 </programlisting>
14805
14806 <para>
14807 There are drivers of two kinds : stream drivers (driver that
14808 connects to servers through TCP or other means of connection)
14809 and file drivers (driver that are based on filesystem)
14810
14811 This function can only be used by stream drivers and
14812 this connects a stream to the session
14813 </para>
14814 </sect2>
14815
14816 <sect2>
14817 <title>mailsession_connect_path</title>
14818
14819 <programlisting>
14820#include &lt;libetpan/libetpan.h&gt;
14821
14822int mailsession_connect_path(mailsession * session, char * path);
14823 </programlisting>
14824
14825 <para>
14826 This function can only be used by file drivers and
14827 selects the main path of the session.
14828 </para>
14829 </sect2>
14830
14831 <sect2>
14832 <title>mailsession_starttls</title>
14833
14834 <programlisting>
14835#include &lt;libetpan/libetpan.h&gt;
14836
14837int mailsession_starttls(mailsession * session);
14838 </programlisting>
14839
14840 <para>
14841 This switches the current connection to TLS (secure layer).
14842 This will only work with stream drivers.
14843 </para>
14844 </sect2>
14845
14846 <sect2>
14847 <title>mailsession_login</title>
14848
14849 <programlisting>
14850#include &lt;libetpan/libetpan.h&gt;
14851
14852int mailsession_login(mailsession * session,
14853 char * userid, char * password);
14854 </programlisting>
14855
14856 <para>
14857 This notifies the login and the password to authenticate
14858 to the session.
14859 </para>
14860 </sect2>
14861
14862 <sect2>
14863 <title>mailsession_logout</title>
14864
14865 <programlisting>
14866#include &lt;libetpan/libetpan.h&gt;
14867
14868int mailsession_logout(mailsession * session);
14869 </programlisting>
14870
14871 <para>
14872 This function disconnects the session and closes the stream.
14873 </para>
14874 </sect2>
14875
14876 <sect2>
14877 <title>mailsession_noop</title>
14878
14879 <programlisting>
14880#include &lt;libetpan/libetpan.h&gt;
14881
14882int mailsession_noop(mailsession * session);
14883 </programlisting>
14884
14885 <para>
14886 This function does no operation on the session, but it can be
14887 used to poll for the status of the connection.
14888 </para>
14889 </sect2>
14890
14891 <sect2>
14892 <title>mailsession_check_folder</title>
14893
14894 <programlisting>
14895#include &lt;libetpan/libetpan.h&gt;
14896
14897int mailsession_check_folder(mailsession * session);
14898 </programlisting>
14899
14900 <para>
14901 This function makes a checkpoint of the session.
14902 </para>
14903 </sect2>
14904
14905 <sect2>
14906 <title>mailsession_select_folder</title>
14907
14908 <programlisting>
14909#include &lt;libetpan/libetpan.h&gt;
14910
14911int mailsession_select_folder(mailsession * session, char * mb);
14912 </programlisting>
14913
14914 <para>
14915 This function selects a mailbox.
14916 </para>
14917 </sect2>
14918
14919 <sect2>
14920 <title>mailsession_expunge_folder</title>
14921
14922 <programlisting>
14923#include &lt;libetpan/libetpan.h&gt;
14924
14925int mailsession_expunge_folder(mailsession * session);
14926 </programlisting>
14927
14928 <para>
14929 This function deletes all messages marked for deletion.
14930 </para>
14931 </sect2>
14932
14933 <sect2>
14934 <title>mailsession_status_folder</title>
14935
14936 <programlisting>
14937#include &lt;libetpan/libetpan.h&gt;
14938
14939int mailsession_status_folder(mailsession * session, char * mb,
14940 uint32_t * result_messages, uint32_t * result_recent,
14941 uint32_t * result_unseen);
14942 </programlisting>
14943
14944 <para>
14945 This function queries the status of the folder
14946 (number of messages, number of recent messages, number of
14947 unseen messages).
14948 </para>
14949 </sect2>
14950
14951 <sect2>
14952 <title>mailsession_messages_number</title>
14953
14954 <programlisting>
14955#include &lt;libetpan/libetpan.h&gt;
14956
14957int mailsession_messages_number(mailsession * session, char * mb,
14958 uint32_t * result);
14959 </programlisting>
14960
14961 <para>
14962 This function queries the number of messages in the folder.
14963 </para>
14964 </sect2>
14965
14966 <sect2>
14967 <title>mailsession_recent_number</title>
14968
14969 <programlisting>
14970#include &lt;libetpan/libetpan.h&gt;
14971
14972int mailsession_recent_number(mailsession * session,
14973 char * mb, uint32_t * result);
14974 </programlisting>
14975
14976 <para>
14977 This function queries the number of recent messages in the
14978 folder.
14979 </para>
14980 </sect2>
14981
14982 <sect2>
14983 <title>mailsession_unseen_number</title>
14984
14985 <programlisting>
14986#include &lt;libetpan/libetpan.h&gt;
14987
14988int mailsession_unseen_number(mailsession * session, char * mb,
14989 uint32_t * result);
14990 </programlisting>
14991
14992 <para>
14993 This function queries the number of unseen messages in the
14994 folder.
14995 </para>
14996 </sect2>
14997
14998 <sect2>
14999 <title>mailsession_append_message</title>
15000
15001 <programlisting>
15002#include &lt;libetpan/libetpan.h&gt;
15003
15004int mailsession_append_message(mailsession * session,
15005 char * message, size_t size);
15006 </programlisting>
15007
15008 <para>
15009 This adds a RFC 2822 message to the current mailbox.
15010 </para>
15011 </sect2>
15012
15013 <sect2>
15014 <title>mailsession_get_messages_list</title>
15015
15016 <programlisting>
15017#include &lt;libetpan/libetpan.h&gt;
15018
15019int mailsession_get_messages_list(mailsession * session,
15020 struct mailmessage_list ** result);
15021 </programlisting>
15022
15023 <para>
15024 This function returns the list of messages
15025 of the current mailbox.
15026 </para>
15027 </sect2>
15028
15029 <sect2>
15030 <title>mailsession_get_envelopes_list</title>
15031
15032 <programlisting>
15033#include &lt;libetpan/libetpan.h&gt;
15034
15035int mailsession_get_envelopes_list(mailsession * session,
15036 struct mailmessage_list * result);
15037 </programlisting>
15038
15039 <para>
15040 This function fills the parsed fields in the
15041 <command>mailmessage</command> structures
15042 (see <xref linkend="mailmessage">)
15043 of the mailmessage_list
15044 (see <xref linkend="mailmessage-list">).
15045 </para>
15046 </sect2>
15047
15048 <sect2>
15049 <title>mailsession_get_message</title>
15050
15051 <programlisting>
15052#include &lt;libetpan/libetpan.h&gt;
15053
15054int mailsession_get_message(mailsession * session,
15055 uint32_t num, mailmessage ** result);
15056 </programlisting>
15057
15058 <para>
15059 This function returns a <command>mailmessage</command>
15060 (see <xref linkend="mailmessage">) structure that
15061 corresponds to the given message number.
15062 </para>
15063
15064 <warning>
15065 <para>
15066 <command>mailsession_get_message_by_uid()</command> should
15067 be used instead.
15068 </para>
15069 </warning>
15070 </sect2>
15071
15072 <sect2>
15073 <title>mailsession_get_message_by_uid</title>
15074
15075 <programlisting>
15076#include &lt;libetpan/libetpan.h&gt;
15077
15078int mailsession_get_message_by_uid(mailsession * session,
15079 const char * uid, mailmessage ** result);
15080 </programlisting>
15081
15082 <para>
15083 This function returns a mailmessage structure
15084 that corresponds to the given message unique identifier.
15085 This is currently implemented only for cached drivers.
15086 </para>
15087 <warning>
15088 <para>
15089 That deprecates the use of
15090 <command>mailsession_get_message()</command>.
15091 </para>
15092 </warning>
15093 </sect2>
15094 </sect1>
15095 </chapter>
15096
15097</book>
diff --git a/kmicromail/libetpan/doc/DOCUMENTATION b/kmicromail/libetpan/doc/DOCUMENTATION
new file mode 100644
index 0000000..4f66519
--- a/dev/null
+++ b/kmicromail/libetpan/doc/DOCUMENTATION
@@ -0,0 +1,654 @@
11/ Introduction
2---------------
3
4libEtPan! is mainly a library that will handle all kind of mailbox access.
5For example: IMAPrev4, POP3, NNTP, mbox, MH.
6
7You have two kinds of mailbox access, either using low-level functions
8with a different interface for each kind of access or using higher-level
9functions, using a driver to wrap the higher-level API.
10
11
122/ Low-level
13------------
14
152.1/ IMAP4rev1 - Internet Message Access Protocol - Version 4rev1
16-----------------------------------------------------------------
17
18Each command of the IMAP4rev1 Standard (RFC 2060) is implemented in
19the IMAP4rev1 module. Directory imap/.
20
212.1.1/ References
22
23- RFC 2060 - INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1
24- draft-crispin-imapv-15.txt
25
26Not yet implemented :
27
28- draft-crispin-imapv-20.txt
29
302.1.2/ Dependencies
31
32- tools/
33
342.1.3/ Files descriptions
35
36description of header files :
37mailimap.[ch] -- functions that implements each IMAP4rev1 command
38mailimap_helper.[ch] -- helper interface for the previous functions
39mailimap_types.[ch] -- definition of types and constructors for these
40 types
41mailimap_types_helper.[ch] -- contains function definitions that will help
42 to create data necessary to use IMAP4rev1 module
43mailimap_socket.[ch] -- provides a function to connect to an
44 IMAP4rev1 server over TCP
45mailimap_ssl.[ch] -- provides a function to connect to an
46 IMAP4rev1 server over TLS layer
47
482.1.4/ Interface
49
50Include for this module is mailimap.h and includes all other headers.
51
52
53The interface of IMAP4rev1 is documented in the following files :
54
55mailimap.h
56mailimap_types.h
57mailimap_types_helper.h
58
59
602.2/ POP3 - Post Office Protocol - Version 3
61--------------------------------------------
62
63Each command of the POP3 Standard (RFC 1939 and RFC 2449) is implemented
64in the POP3 module. Directory pop3/.
65
662.1.1/ References
67
68- RFC 1939 - Post Office Protocol - Version 3
69- RFC 2449 - POP3 Extension Mechanism (CAPA)
70
71Not yet implemented :
72
73- RFC 1734 - POP3 AUTHentication command
74
752.1.2/ Dependencies
76
77- tools/
78
792.2.3/ Files descriptions
80
81mailpop3.[ch] -- functions that implements each POP3 command
82mailpop3_helper.[ch] -- helper interface for the previous functions
83mailpop3_socket.[ch] -- provides a function to connect to a
84 POP3 server over TCP
85mailpop3_ssl.[ch] -- provides a function to connect to a
86 POP3 server over TLS layer
87
882.2.4/ Interface
89
90Include for this module is mailpop3.h and includes all other headers.
91
92There is not yet documentation for POP3 module.
93
94
952.3/ NNTP - Network News Transfer Protocol
96------------------------------------------
97
98Each command of the NNTP Standard (RFC 977 and RFC 2980) is implemented
99in the NNTP module. Directory nntp/.
100
1012.3.1/ References
102
103- RFC 977 - Network News Transfer Protocol
104- RFC 2980 - Common NNTP Extensions
105
106Not yet implemented :
107
108- RFC 1036 - Standard for Interchange of USENET Messages
109- son of RFC 1036 : FTP://zoo.toronto.edu/pub/news.txt.Z
110
1112.3.2/ Dependencies
112
113- tools/
114
1152.3.3/ Files descriptions
116
117newsnntp.[ch] -- functions that implements each NNTP command
118newsnntp_socket.[ch] -- provides a function to connect to a
119 NNTP server over TCP
120newsnntp_ssl.[ch] -- provides a function to connect to a
121 POP3 server over TLS layer
122
1232.3.4/ Interface
124
125Include for this module is newsnntp.h and includes all other headers.
126
127There is not yet documentation for NNTP module.
128
129
1302.4/ mbox
131---------
132
133The mbox module provides a set of functions to manipulate mbox mailboxes.
134These functions make a safe lock on the mailbox they work with.
135This module will assign to each message a unique message identifier
136so that we can work with message numbers in mbox files without other
137programs interfer.
138Directory mbox/.
139
1402.4.1/ References
141
142- http://wp.netscape.com/eng/mozilla/2.0/relnotes/demo/content-length.html
143- http://www.qmail.org/qmail-manual-html/man5/mbox.html
144
1452.4.2/ Dependencies
146
147- tools/
148- imf/
149
1502.5.3/ Specific to libEtPan!
151
152- "X-LibEtPan-UID" header
153
1542.5.4/ Files descriptions
155
156mailmbox.[ch] -- functions to manipulate mbox mailboxes.
157mailmbox_parse.[ch] -- this module is in charge of parsing the
158 mbox file content
159mailmbox_types.[ch] -- definition of types and constructors for these
160 types
161
1622.4.5/ Interface
163
164Include for this module is mailmbox.h and includes all other headers.
165
166There is not yet documentation for mbox module.
167
168
1692.5/ MH
170-------
171
172The MH module provides a set of functions to manipulate MH mailboxes.
173Directory mh/.
174
1752.5.1/ References
176
177- almost none
178
1792.5.2/ Dependencies
180
181- tools/
182
1832.5.3/ Files descriptions
184
185mailmh.[ch] -- functions to manipulate MH mailboxes.
186
187
1882.5.4/ Interface
189
190Include for this module is mailmh.h.
191
192There is not yet documentation for MH module.
193
194
1952.6/ IMF - Internet Message Format
196----------------------------------
197
198The IMF module provides functions to parse data given in RFC 2822
199format (Internet Message Format).
200Directory imf/.
201
2022.6.1/ References
203
204- RFC 2822 - Internet Message Format (Not entirely implemented)
205- RFC 2076 - Common Internet Message Headers
206
207Not yet implemented :
208
209- RFC 2298 - An Extensible Message Format
210 for Message Disposition Notifications
211
2122.6.2/ Dependencies
213
214- tools/
215
2162.6.3/ Files descriptions
217
218mailimf.[ch] -- functions to parse RFC 2822 messages.
219mailimf_types.[ch] -- definition of types and constructors for these
220 types
221mailimf_types_helper.[ch] -- contains function definitions that will help
222 to create data necessary to use IMF module.
223mailimf_write.[ch] -- functions that output RFC 2822 messages or
224 sub-part of the messages in a (FILE *).
225
2262.6.4/ Interface
227
228Include for this module is mailimf.h and includes all other headers.
229
230The interface of IMAP4rev1 is documented in the following files :
231
232mailimf.h
233mailimf_types.h
234mailimf_types_helper.h
235mailimf_write.h
236
237
2382.7/ MIME - Multipurpose Internet Mail Extensions
239-------------------------------------------------
240
241The MIME module provides functions to parse structure of MIME messages.
242Directory mime/.
243
2442.7.1/ References
245
246- RFC 2045 - Multipurpose Internet Mail Extensions (MIME) Part One: Format of
247 Internet Message Bodies.
248- RFC 2047 - MIME (Multipurpose Internet Mail Extensions) Part Three: Message
249 Header Extensions for Non-ASCII Text.
250- RFC 2183 - Communicating Presentation Information in Internet Messages:
251 The Content-Disposition Header Field
252
253Not implemented :
254
255- RFC 2046 - Multipurpose Internet Mail Extensions (MIME) Part Two: Media
256 Types.
257
2582.7.2/ Dependencies
259
260- tools/
261- imf/
262
2632.7.3/ Files descriptions
264
265mailmime.[ch] -- functions to parse the MIME fields (RFC 2045).
266mailmime_content.[ch] -- functions to parse the MIME message. You get
267 the different parts and you can decode them.
268mailmime_decode.[ch] -- functions to parse the MIME-encoded fields.
269mailmime_disposition.[ch] -- functions to parse the Content-Disposition field
270 (RFC 2183)
271mailmime_types.[ch] -- definition of types and constructors for these
272 types
273mailmime_types_helper.[ch] -- contains function definitions that will help
274 to create data necessary to use MIME module.
275mailmime_write.[ch] -- functions that output MIME messages or
276 sub-part of the messages in a (FILE *).
277
2782.7.4/ Interface
279
280Include for this module is mailmime.h and includes all other headers.
281
282There is not yet documentation for MIME module.
283
284
2852.8/ SMTP - Simple Mail Transfer Protocol
286-----------------------------------------
287
288Each command of the SMTP Standard (RFC 2821 and RFC 1891) is implemented
289in the SMTP module. Directory smtp/.
290
2912.8.1/ References
292
293- RFC 2821 - Simple Mail Transfer Protocol (Not entirely implemented)
294- RFC 1891 - SMTP Service Extension for Delivery Status Notifications
295
2962.8.2/ Depencencies
297
298- tools/
299
3002.8.3/ Files descriptions
301
302mailsmtp.[ch] -- functions that implements each SMTP command
303mailsmtp_helper.[ch] -- functions to get an easier use of SMTP module
304mailsmtp_socket.[ch] -- provides a function to connect to a
305 SMTP server over TCP
306mailsmtp_ssl.[ch] -- provides a function to connect to a
307 SMTP server over TLS layer
308mailsmtp_types.h -- definition of types
309
3102.8.4/ Interface
311
312Include for this module is mailsmtp.h and includes all other headers.
313
314There is not yet documentation for MIME module.
315
316
3172.9/ Miscellaneous
318
3192.9.1/ References
320
321- RFC 2234 - Augmented BNF for Syntax Specifications: ABNF
322- RFC 2595 - Using TLS with IMAP, POP3 and ACAP
323
3242.9.2/ Tools
325
326tools/ directory contains some tools functions and useful data structures.
327
328alloc.h -- a wrapper on malloc()
329carray.[ch] -- an array, that grows automatically when elements
330 are added.
331charconv.[ch] -- character set converter. For example, it will
332 translate an iso-8859-1 string to an utf-8 string.
333chash.[ch] -- a hash table which keys can be anything
334cinthash.[ch] -- a hash table which keys are integers
335 (should be removed and replaced with chash)
336clist.[ch] -- a double-linked list
337connect.[ch] -- easy interface to connect a TCP server
338hmac_md5.h
339md5.[ch]
340md5global.h -- MD5 calculation
341mail.h -- some constants
342maildb_helper.[ch] -- wrappers to DB 2.x 3.x or 4.x
343maillock.[ch] -- safely lock a given file
344mailstream.[ch] -- stream interface - buffered reading and writing
345 on files/socket/SSL connection
346mailstream_helper.[ch] -- useful functions for stream
347 (for example: read a line)
348mailstream_low.[ch] -- driver interface for a stream
349mailstream_socket.[ch] -- stream driver for file descriptors (includes socket)
350mailstream_ssl.[ch] -- stream driver for SSL connection
351mailstream_types.h -- data structure definition
352mapping.[ch] -- map parts of files in memory (no more used)
353mmapstring.[ch] -- a string, that grows automatically when data
354 are added.
355
356
3573/ Higher-level
358---------------
359
360The higher level will allow us to query folder informations or to get
361messages information or content.
362
363There is four kinds of identities :
364- storage
365- folders
366- session
367- messages
368
369In the higher-level interface, you manipulate data types from IMF and
370MIME module, plus additionnal data types of higher-level.
371
372
3733.1/ Objects
374------------
375
3763.1.1/ Storage
377
378A storage (struct mail_storage) represents whether a server or
379a main path, It can be an IMAP server, the root path of a MH or a mbox file.
380
381
3823.1.2/ Folders
383
384A folder can be created from a storage.
385Folders (struct mail_folder) are the mailboxes we can choose in the
386server or as sub-folder of the main path.
387
388Folders for IMAP are the IMAP mailboxes, for MH this is one of the
389folder of the MH storage, for mbox, there is only one folder, the
390mbox file content;
391
392
3933.1.3/ Session
394
395Storage and folders communicate with the lower-layer through the
396mail session data structure.
397
398A mail session (struct mailsession) is a mail access to a server
399or a mail access in the local file system. It allow us to send commands
400to the mail access.
401
402A mail storage is using a mail session to communicate.
403A folder folder also uses a mail session to get information or to send
404information. It can be the same session or not, depdending of the
405implementation.
406
407
4083.1.4/ Messages
409
410From a session, we can get a message (struct mailmessage) to read.
411
412
4133.2/ Drivers
414------------
415
416For a mail access, three drivers exist.
417One for storage, one for session, one for message.
418Note that the folder access rely only on session driver.
419
420
4213.2.1/ storage driver interface
422
423 mail_storage_driver is the driver structure for mail storage
424
425 - name is the name of the driver
426
427 - connect() connects the storage to the remote access or to
428 the path in the local filesystem.
429
430 - get_folder() can have two kinds of behaviour.
431 Either it creates a new session and independant from the session
432 used by the storage and select the given mailbox or
433 it selects the given mailbox in the current session.
434 It depends on the efficiency of the mail driver.
435
436 - free_data() frees the data created with mail_storage constructor.
437
438 a constructor for each kind of access has to be implemented.
439
440
4413.2.2/ session driver interface
442
443 maildriver is the driver structure for mail sessions
444
445 - name is the name of the driver
446
447 - initialize() is the function that will initializes a data structure
448 specific to the driver, it returns a value that will be stored
449 in the field data of the session.
450 The field data of the session is the state of the session,
451 the internal data structure used by the driver.
452 It is called when creating the mailsession structure with
453 mailsession_new().
454
455 - uninitialize() frees the structure created with initialize()
456
457 - parameters() implements functions specific to the given mail access
458
459 - connect_stream() connects a stream to the session
460
461 - connect_path() notify a main path to the session
462
463 - starttls() changes the current stream to a TLS stream
464
465 - login() notifies the user and the password to authenticate to the
466 session
467
468 - logout() exits the session and closes the stream
469
470 - noop() does no operation on the session, but it can be
471 used to poll for the status of the connection.
472
473 - check_folder() makes a checkpoint of the session
474
475 - select_folder() selects a mailbox
476
477 - expunge_folder() deletes all messages marked \Deleted
478
479 - status_folder() queries the status of the folder
480 (number of messages, number of recent messages, number of
481 unseen messages)
482
483 - append_message() adds a RFC 2822 message to the current
484 given mailbox
485
486 - get_messages_list() returns the list of message numbers
487 of the current mailbox.
488
489 - get_envelopes_list() fills the parsed fields in the
490 mailmessage structures of the mail_envelopes_list.
491
492 - remove_message() removes the given message from the mailbox.
493 The message is permanently deleted.
494
495 - get_message returns a mailmessage structure that corresponds
496 to the given message number.
497
498
4993.2.3/ message driver interface
500
501 mailmessage_driver is the driver structure to get information from messages.
502
503 - name is the name of the driver
504
505 - initialize() is the function that will initializes a data structure
506 specific to the driver, it returns a value that will be stored
507 in the field data of the mailsession.
508 The field data of the session is the state of the session,
509 the internal data structure used by the driver.
510 It is called when initializing the mailmessage structure with
511 mailmessage_init().
512
513 - uninitialize() frees the structure created with initialize().
514 It will be called by mailmessage_free().
515
516 - flush() will free from memory all temporary structures of the message
517 (for example, the MIME structure of the message).
518
519 - fetch_result_free() will free all strings resulted by fetch() or
520 any fetch_xxx() functions that returns a string.
521
522 - fetch() returns the content of the message (headers and text).
523
524 - fetch_header() returns the content of the headers.
525
526 - fetch_body() returns the message text (message content without headers)
527
528 - fetch_size() returns the size of the message content.
529
530 - get_bodystructure() returns the MIME structure of the message.
531
532 - fetch_section() returns the content of a given MIME part
533
534 - fetch_section_header() returns the header of the message
535 contained by the given MIME part.
536
537 - fetch_section_mime() returns the MIME headers of the
538 given MIME part.
539
540 - fetch_section_body() returns the text (if this is a message, this is the
541 message content without headers) of the given MIME part.
542
543 - fetch_envelope() returns a mailimf_fields structure, with a list of
544 fields chosen by the driver.
545
546 - get_flags() returns a the flags related to the message.
547 When you want to get flags of a message, you have to make sure to
548 call get_flags() at least once before using directly message->flags.
549
550
5513.3/ Higher level interface
552---------------------------
553
5543.3.1/ Files descriptions
555
556generic_cache.[ch] -- functions that implements cache and
557 flags storing mechanism
558imapdriver.[ch] -- IMAP driver for session
559imapdriver_cached.[ch] -- IMAP driver for session, using cache,
560 IMAP already has flags.
561imapdriver_cached_message.[ch] -- IMAP driver for message, using cache
562 IMAP already has flags.
563imapdriver_message.[ch] -- IMAP driver for message
564imapdriver_types.[ch] -- tools function for IMAP driver (types
565 conversion from IMAP module).
566imapstorage.[ch] -- IMAP driver for storage
567imfcache.[ch] -- implements cache for parsed fields
568libetpan.h -- includes all necessary header files to
569 use libEtPan!
570maildriver.[ch] -- wrappers to calls to the session driver
571maildriver_tools.[ch] -- default implementation for drivers,
572 when the driver does not parse the
573 messages.
574maildriver_types.[ch] -- data types declaration and constructors
575maildriver_types_helper.[ch] -- easy data creation
576mailmessage.[ch] -- wrappers to calls to the message driver
577mailstorage.[ch] -- storage creation, calls to the storage
578 driver and implementation of folders.
579mailstorage_tools.[ch] -- tools for storage (connection)
580mailthread.[ch] -- threading: collection of the mails
581 into a treee
582mboxdriver.[ch] -- mbox driver for session
583mboxdriver_cached.[ch] -- mbox driver for session, using flags
584 and cache
585mboxdriver_cached_message.[ch] -- mbox driver for message, using flags
586 and cache
587mboxdriver_message.[ch] -- mbox driver for message
588mboxdriver_tools.[ch] -- mbox driver common functions
589mboxstorage.[ch] -- mbox driver for storage
590mhdriver.[ch] -- MH driver for session
591mhdriver_cached.[ch] -- MH driver for session, using flags
592 and cache
593mhdriver_cached_message.[ch] -- MH driver for message, using flags
594 and cache.
595mhdriver_message.[ch] -- MH driver for message
596mhdriver_tools.[ch] -- MH driver common functions
597mhstorage.[ch] -- MH driver for storage
598nntpdriver.[ch] -- NNTP driver for session
599nntpdriver_cached.[ch] -- NNTP driver for session, using flags
600 and cache
601nntpdriver_cached_message.[ch] -- NNTP driver for message, using flags
602 and cache
603nntpdriver_message.[ch] -- NNTP driver for message
604nntpdriver_tools.[ch] -- NNTP driver common functions
605nntpstorage.[ch] -- NNTP driver for storage
606pop3driver.[ch] -- POP3 driver for session
607pop3driver_cached.[ch] -- POP3 driver for session, using flags
608 and cache
609pop3driver_cached_message.[ch] -- POP3 driver for message, using flags
610 and cache
611pop3driver_message.[ch] -- POP3 driver for message
612pop3driver_tools.[ch] -- POP3 driver common functions
613pop3storage.[ch] -- POP3 driver for storage
614
615
6163.3.2/ Interfaces
617
618Include for this module is libetpan.h and includes all other headers.
619
620
621The interface of higher layer is documented in the following files :
622
623maildriver.h
624maildriver_types.h
625maildriver_types_helper.h
626mailmessage.h
627mailstorage.h
628mailstorage_types.[h]
629mailthread.h
630
631
6324/ Architecture
633---------------
634
635(see layer.fig)
636
637
6385/ Example of use
639-----------------
640
641You can find some example in tests/
642
643
6446/ Constraints
645--------------
646
647- libEtPan! must run on a system where mmap() is available.
648
649- for mbox particularly, libEtPan! make assumption on the fact that a
650 file can be entirely mapped into memory. But if you don't read
651 mailboxes of 1 Go, it should be fine.
652
653
654
diff --git a/kmicromail/libetpan/doc/README.sgml b/kmicromail/libetpan/doc/README.sgml
new file mode 100644
index 0000000..1ddbf96
--- a/dev/null
+++ b/kmicromail/libetpan/doc/README.sgml
@@ -0,0 +1,319 @@
1<!doctype book PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
2
3<book id="libetpan-readme">
4 <bookinfo>
5 <date>2003-12-03</date>
6 <title>libEtPan!</title>
7 <authorgroup>
8 <author>
9 <firstname>Viet Hoa</firstname>
10 <surname>DINH</surname>
11 </author>
12 </authorgroup>
13 <copyright>
14 <year>2003</year>
15 <holder>DINH Viet Hoa</holder>
16 </copyright>
17 </bookinfo>
18 <toc></toc>
19
20 <chapter id="introduction">
21 <title>Introduction</title>
22
23 <!-- description -->
24 <sect1 id="description">
25 <title>Description</title>
26 <para>
27 The purpose of this mail library is to provide a portable,
28 efficient middleware for different kinds of mail access
29 (IMAPrev4, POP3, NNTP, mbox, MH, Maildir).
30 </para>
31
32 <para>
33 You have two kinds of mailbox access, either using low-level
34 functions with a different interface for each kind of access
35 or using higher-level functions, using a driver to wrap the
36 higher-level API. The API will be the same for each kind of
37 mail access using the higher-level API.
38 </para>
39 </sect1>
40
41 <!-- authors -->
42 <sect1 id="author">
43 <title>Author</title>
44 <sect2 id="main-auth">
45 <title>Main author</title>
46 <para>
47 DINH Viet Hoa <email>hoa@users.sourceforge.net</email>
48 </para>
49 </sect2>
50 <sect2 id="contrib">
51 <title>Contributors</title>
52 <para>
53 <itemizedlist>
54 <listitem>
55 <para>
56 Wim Delvaux <!-- wim.delvaux.adaptiveplanet.com -->
57 </para>
58 </listitem>
59 <listitem>
60 <para>
61 Melvin Hadasht <!-- melvin.hadasht@free.fr -->
62 </para>
63 </listitem>
64 <listitem>
65 <para>
66 David Woodhouse <!-- dwmw2@infradead.org -->
67 </para>
68 </listitem>
69 <listitem>
70 <para>
71 Juergen Graf <!-- libetpan@codeguy.org -->
72 </para>
73 </listitem>
74 <listitem>
75 <para>
76 Zsolt VARGA <!-- redax@redax.hu -->
77 </para>
78 </listitem>
79 <listitem>
80 <para>
81 Gael Roualland <!-- gael.roualland@dial.oleane.com -->
82 </para>
83 </listitem>
84 </itemizedlist>
85 </para>
86 </sect2>
87 </sect1>
88 </chapter>
89
90 <!-- installation -->
91 <chapter id="installation">
92 <title>Installation</title>
93
94 <sect1 id="dependencies">
95 <title>Dependencies</title>
96
97 <!-- dependencies for users -->
98 <sect2 id="depend-users">
99 <title>Dependencies for users</title>
100
101 <itemizedlist>
102 <listitem>
103 <para>
104 <ulink url="http://www.openssl.org">OpenSSL</ulink>
105 (optional but recommended)
106 </para>
107 </listitem>
108 <listitem>
109 <para>
110 <ulink url="http://www.sleepycat.com">Berkeley
111 DB</ulink> (optional but recommended)
112 </para>
113 </listitem>
114 <listitem>
115 <para>
116 POSIX Thread (required)
117 </para>
118 </listitem>
119 </itemizedlist>
120 </sect2>
121 <!-- dependencies for developers -->
122 <sect2 id="depend-developers">
123 <title>Dependencies for developers</title>
124
125 <itemizedlist>
126 <listitem>
127 <para>
128 <ulink url="http://www.gnu.org/software/autoconf">
129 autoconf
130 </ulink>
131 2.13
132 </para>
133 </listitem>
134 <listitem>
135 <para>
136 <ulink url="http://www.gnu.org/software/automake">
137 automake
138 </ulink>
139 1.4
140 </para>
141 </listitem>
142 <listitem>
143 <para>
144 <ulink
145 url="http://www.gnu.org/software/libtool/libtool.html">
146 libtool
147 </ulink>
148 1.4.3
149 </para>
150 </listitem>
151 </itemizedlist>
152 </sect2>
153 </sect1>
154 <!-- packages -->
155 <sect1 id="packages">
156 <title>Existing packages</title>
157
158 <itemizedlist>
159 <listitem>
160 <para>
161 Before you try to compile it, you have to know that packages
162 exist for FreeBSD. (ports/mail/libetpan).
163 This is currently 0.29 for -stable, 0.30 for -current.
164 </para>
165 </listitem>
166 </itemizedlist>
167 </sect1>
168
169 <!-- compilation -->
170 <sect1 id="compilation">
171 <title>Compilation</title>
172
173 <para>
174 Generic installation instructions are in the
175 <filename>INSTALL</filename> file
176 You can pass the following extra options to configure :
177 </para>
178
179 <!-- FreeBSD -->
180 <sect2 id="freebsd">
181 <title>FreeBSD</title>
182 <itemizedlist>
183 <listitem>
184 <para>
185 make sure libiconv is installed from the ports collection (see
186 <command>pkg_info</command>).
187 </para>
188 </listitem>
189 <listitem>
190 <para>
191 issue configure with the following parameter:
192 <screen>
193<prompt>$</prompt> <userinput>./configure --with-libiconv-prefix=/usr/local</userinput>
194 </screen>
195 </para>
196 </listitem>
197 </itemizedlist>
198 </sect2>
199
200 <!-- MacOS X -->
201 <sect2 id="macosx">
202 <title>Mac OS X</title>
203 <itemizedlist>
204 <listitem>
205 <para>
206 You have to configure using the following command line :
207 <command>CPPFLAGS=-I/sw/include LDFLAGS=-L/sw/lib
208 ./configure</command>
209 </para>
210 </listitem>
211 <listitem>
212 <para>
213 in tests/option-parser.c, change the inclusion
214 of <filename>getopt.h</filename> to
215 <filename>gnugetopt/getopt.h</filename>
216 </para>
217 </listitem>
218 <listitem>
219 <para>
220 in <filename>tests/Makefile</filename>, add
221 <command>-I/sw/include</command> for the
222 <command>CFLAGS</command> and
223 -L/sw/lib -lgnugetopt for the LDFLAGS.
224 </para>
225 </listitem>
226 </itemizedlist>
227 </sect2>
228
229 <!-- Linux -->
230 <sect2 id="linux">
231 <title>Linux</title>
232 <itemizedlist>
233 <listitem>
234 <warning>
235 <para>
236 Since libEtPan! is making high usage of
237 <command>mmap()</command> even for
238 writing, when your mailboxes are on
239 <command>NFS</command> filesystem with
240 a Linux server, it is advised to use option
241 <command>no_subtree_check</command> in
242 <filename>/etc/exports</filename>.
243 This should avoid corruption of data.
244 </para>
245 <para>
246 The problem exist in Linux 2.4.22 and earlier versions.
247 </para>
248 </warning>
249 </listitem>
250 <listitem>
251 <para>
252 On RedHat systems, you have to configure using the
253 following command line :
254 <command>./configure --with-openssl=/usr/kerberos</command>
255 </para>
256 </listitem>
257 <listitem>
258 <para>
259 On Debian systems, if the <command>./autogen</command>
260 script fails on missing <command>AM_ICONV</command>, you
261 have to install <command>gettext</command> package.
262 </para>
263 </listitem>
264 </itemizedlist>
265 </sect2>
266
267 <!-- configure -->
268 <sect2 id="configure">
269 <title>configure</title>
270 <para>
271 You can use the following options :
272 </para>
273 <itemizedlist>
274 <listitem>
275 <para>
276 <command>--enable-debug</command> Compiles with
277 debugging turned on
278 </para>
279 </listitem>
280 <listitem>
281 <para>
282 <command>--enable-optim</command> Turns on some
283 optimizations flags for gcc
284 </para>
285 </listitem>
286 <listitem>
287 <para>
288 <command>--without-openssl</command> Disables OpenSSL (do
289 not look for it)
290 </para>
291 </listitem>
292 </itemizedlist>
293 </sect2>
294 <sect2 id="install">
295 <title>Compile and install</title>
296 <para>
297 Download the package and do the following :
298 </para>
299 <programlisting>
300$ tar xzvf libetpan-XX.XX.tar.gz # to decompress the package
301
302$ cd libetpan-XX.XX
303
304$ ./configure --help # to get options of configure
305
306$ ./configure # you can specify your own options
307
308$ make # to compile the package
309
310$ su
311
312# make install
313
314# logout
315 </programlisting>
316 </sect2>
317 </sect1>
318 </chapter>
319</book>
diff --git a/kmicromail/libetpan/doc/depend.dot b/kmicromail/libetpan/doc/depend.dot
new file mode 100644
index 0000000..b12990f
--- a/dev/null
+++ b/kmicromail/libetpan/doc/depend.dot
@@ -0,0 +1,54 @@
1digraph "etPan! library" {
2 mime -> imf;
3
4 "session/message" -> imf;
5 "session/message" -> mime;
6
7 "storage/folder" -> "session/message";
8}
9
10digraph "imap driver" {
11 "imap driver" -> imap;
12 "imap driver" -> imf;
13 "imap driver" -> mime;
14 "imap driver" -> "session/message";
15
16 mime -> imf;
17}
18
19digraph "mbox driver" {
20 "mbox driver" -> mbox;
21 "mbox driver" -> imf;
22 "mbox driver" -> mime;
23 "mbox driver" -> "session/message";
24 "mbox" -> imf;
25
26 mime -> imf;
27}
28
29digraph "mh driver" {
30 "mh driver" -> mh;
31 "mh driver" -> imf;
32 "mh driver" -> mime;
33 "mh driver" -> "session/message";
34
35 mime -> imf;
36}
37
38digraph "pop3 driver" {
39 "pop3 driver" -> pop3;
40 "pop3 driver" -> imf;
41 "pop3 driver" -> mime;
42 "pop3 driver" -> "session/message";
43
44 mime -> imf;
45}
46
47digraph "nntp driver" {
48 "nntp driver" -> nntp;
49 "nntp driver" -> imf;
50 "nntp driver" -> mime;
51 "nntp driver" -> "session/message";
52
53 mime -> imf;
54}
diff --git a/kmicromail/libetpan/doc/layer.fig b/kmicromail/libetpan/doc/layer.fig
new file mode 100644
index 0000000..ed41783
--- a/dev/null
+++ b/kmicromail/libetpan/doc/layer.fig
@@ -0,0 +1,39 @@
1#FIG 3.2
2Landscape
3Center
4Metric
5A4
6100.00
7Single
8-2
91200 2
102 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
11 900 3150 12150 3150 12150 3825 900 3825 900 3150
122 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
13 900 3825 12150 3825 12150 4500 900 4500 900 3825
142 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
15 3150 3150 3150 3825
162 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
17 5400 3150 5400 3825
182 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
19 7650 3150 7650 3825
202 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
21 9900 3150 9900 3825
222 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 7
23 12150 3150 900 3150 900 2475 12825 2475 12825 4500 12150 4500
24 12150 3150
252 3 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 7
26 900 2475 900 1800 13500 1800 13500 4500 12825 4500 12825 2475
27 900 2475
282 3 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 8
29 900 4500 225 4500 225 1125 13500 1125 13500 1800 900 1800
30 900 4500 900 4500
314 0 0 50 0 16 20 0.0000 4 210 1410 1305 3600 IMAP4rev1\001
324 0 0 50 0 16 20 0.0000 4 210 450 10800 3600 MH\001
334 0 0 50 0 16 20 0.0000 4 210 720 8370 3555 mbox\001
344 0 0 50 0 16 20 0.0000 4 210 795 6120 3600 NNTP\001
354 0 0 50 0 16 20 0.0000 4 210 765 3870 3600 POP3\001
364 0 0 50 0 16 20 0.0000 4 270 1620 5670 2880 session layer\001
374 0 0 50 0 16 20 0.0000 4 270 2730 5085 2250 storage / folders layer\001
384 0 0 50 0 16 20 0.0000 4 210 1500 5760 4275 IMF / MIME\001
394 0 0 50 0 16 20 0.0000 4 270 1395 5670 1575 application\001
diff --git a/kmicromail/libetpan/generic/.libs/libmaildriver.a b/kmicromail/libetpan/generic/.libs/libmaildriver.a
new file mode 100644
index 0000000..9cbc924
--- a/dev/null
+++ b/kmicromail/libetpan/generic/.libs/libmaildriver.a
Binary files differ
diff --git a/kmicromail/libetpan/generic/TODO b/kmicromail/libetpan/generic/TODO
new file mode 100644
index 0000000..fb992cd
--- a/dev/null
+++ b/kmicromail/libetpan/generic/TODO
@@ -0,0 +1,9 @@
1- add UID to non-cached drivers, help clients to recognize messages
2- move IMAP UID cache to non-cached driver
3- fix message size (put it in cache)
4- XXX : fetch body in nntp do not use generic_fetch_body
5- add flags prototype to add or remove flags
6- change prototype of append_message (add flags)
7- cache bodystructures
8- search is not implemented
9- list of folder new implementation
diff --git a/kmicromail/libetpan/generic/data_message_driver.c b/kmicromail/libetpan/generic/data_message_driver.c
new file mode 100644
index 0000000..26cb808
--- a/dev/null
+++ b/kmicromail/libetpan/generic/data_message_driver.c
@@ -0,0 +1,119 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "data_message_driver.h"
37
38#include "mailmessage.h"
39#include "mailmessage_tools.h"
40
41#include <unistd.h>
42#include <sys/mman.h>
43#include <sys/types.h>
44#include <sys/stat.h>
45#include <fcntl.h>
46#include <string.h>
47#include <stdlib.h>
48
49static int fetch_size(mailmessage * msg, size_t * result)
50{
51 struct generic_message_t * msg_data;
52
53 msg_data = msg->msg_data;
54 * result = msg_data->msg_length;
55
56 return MAIL_NO_ERROR;
57}
58
59
60static mailmessage_driver local_data_message_driver = {
61 .msg_name = "data",
62
63 .msg_initialize = mailmessage_generic_initialize,
64 .msg_uninitialize = mailmessage_generic_uninitialize,
65
66 .msg_flush = mailmessage_generic_flush,
67 .msg_check = NULL,
68
69 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
70
71 .msg_fetch = mailmessage_generic_fetch,
72 .msg_fetch_header = mailmessage_generic_fetch_header,
73 .msg_fetch_body = mailmessage_generic_fetch_body,
74 .msg_fetch_size = fetch_size,
75 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
76 .msg_fetch_section = mailmessage_generic_fetch_section,
77 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
78 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
79 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
80 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
81
82 .msg_get_flags = NULL,
83};
84
85mailmessage_driver * data_message_driver = &local_data_message_driver;
86
87
88
89mailmessage * data_message_init(char * data, size_t len)
90{
91 struct generic_message_t * msg_data;
92 mailmessage * msg;
93 int r;
94
95 msg = mailmessage_new();
96 if (msg == NULL)
97 goto err;
98
99 r = mailmessage_init(msg, NULL, data_message_driver, 0, len);
100 if (r < 0)
101 goto free;
102
103 msg_data = msg->msg_data;
104 msg_data->msg_fetched = 1;
105 msg_data->msg_message = data;
106 msg_data->msg_length = len;
107
108 return msg;
109
110 free:
111 mailmessage_free(msg);
112 err:
113 return NULL;
114}
115
116void data_message_detach_mime(mailmessage * msg)
117{
118 msg->msg_mime = NULL;
119}
diff --git a/kmicromail/libetpan/generic/data_message_driver.h b/kmicromail/libetpan/generic/data_message_driver.h
new file mode 100644
index 0000000..e0ee752
--- a/dev/null
+++ b/kmicromail/libetpan/generic/data_message_driver.h
@@ -0,0 +1,50 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef DATA_MESSAGE_DRIVER_H
37
38#define DATA_MESSAGE_DRIVER_H
39
40#include <libetpan/mailmessage.h>
41
42#define LIBETPAN_DATA_MESSAGE
43
44extern mailmessage_driver * data_message_driver;
45
46mailmessage * data_message_init(char * data, size_t len);
47
48void data_message_detach_mime(mailmessage * msg);
49
50#endif
diff --git a/kmicromail/libetpan/generic/generic_cache.c b/kmicromail/libetpan/generic/generic_cache.c
new file mode 100644
index 0000000..d23f9cb
--- a/dev/null
+++ b/kmicromail/libetpan/generic/generic_cache.c
@@ -0,0 +1,729 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "generic_cache.h"
37
38#include "libetpan-config.h"
39
40#include <unistd.h>
41#include <string.h>
42#include <sys/mman.h>
43#include <stdio.h>
44#include <sys/types.h>
45#include <sys/stat.h>
46#include <fcntl.h>
47#include <unistd.h>
48#include <stdlib.h>
49
50#include "maildriver_types.h"
51#include "imfcache.h"
52#include "chash.h"
53#include "mailmessage.h"
54#include "mail_cache_db.h"
55
56int generic_cache_create_dir(char * dirname)
57{
58 struct stat buf;
59 int r;
60
61 r = stat(dirname, &buf);
62 if (r != 0) {
63 r = mkdir(dirname, 0700);
64
65 if (r < 0)
66 return MAIL_ERROR_FILE;
67 }
68 else {
69 if (!S_ISDIR(buf.st_mode))
70 return MAIL_ERROR_FILE;
71 }
72
73 return MAIL_NO_ERROR;
74}
75
76int generic_cache_store(char * filename, char * content, size_t length)
77{
78 int fd;
79 char * str;
80
81 fd = open(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
82 if (fd == -1)
83 return MAIL_ERROR_FILE;
84
85 if (ftruncate(fd, length) < 0)
86 return MAIL_ERROR_FILE;
87
88 str = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
89 if (str == MAP_FAILED)
90 return MAIL_ERROR_FILE;
91
92 memcpy(str, content, length);
93 msync(str, length, MS_SYNC);
94 munmap(str, length);
95
96 close(fd);
97
98 return MAIL_NO_ERROR;
99}
100
101int generic_cache_read(char * filename, char ** result, size_t * result_len)
102{
103 int fd;
104 char * str;
105 struct stat buf;
106 MMAPString * mmapstr;
107 char * content;
108 int res;
109
110 if (stat(filename, &buf) < 0) {
111 res = MAIL_ERROR_CACHE_MISS;
112 goto err;
113 }
114
115 fd = open(filename, O_RDONLY);
116 if (fd == -1) {
117 res = MAIL_ERROR_CACHE_MISS;
118 goto err;
119 }
120
121 str = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
122 if (str == MAP_FAILED) {
123 res = MAIL_ERROR_FILE;
124 goto close;
125 }
126
127 mmapstr = mmap_string_new_len(str, buf.st_size);
128 if (mmapstr == NULL) {
129 res = MAIL_ERROR_MEMORY;
130 goto unmap;
131 }
132
133 if (mmap_string_ref(mmapstr) < 0) {
134 res = MAIL_ERROR_MEMORY;
135 goto free;
136 }
137
138 content = mmapstr->str;
139
140 munmap(str, buf.st_size);
141 close(fd);
142
143 * result = content;
144 * result_len = buf.st_size;
145
146 return MAIL_NO_ERROR;
147
148 free:
149 mmap_string_free(mmapstr);
150 unmap:
151 munmap(str, buf.st_size);
152 close:
153 close(fd);
154 err:
155 return res;
156}
157
158static int flags_extension_read(MMAPString * mmapstr, size_t * index,
159 clist ** result)
160{
161 clist * list;
162 int r;
163 uint32_t count;
164 uint32_t i;
165 int res;
166
167 r = mailimf_cache_int_read(mmapstr, index, &count);
168 if (r != MAIL_NO_ERROR) {
169 res = r;
170 goto err;
171 }
172
173 list = clist_new();
174 if (list == NULL) {
175 res = MAIL_ERROR_MEMORY;
176 goto err;
177 }
178
179 for(i = 0 ; i < count ; i++) {
180 char * str;
181
182 r = mailimf_cache_string_read(mmapstr, index, &str);
183 if (r != MAIL_NO_ERROR) {
184 res = r;
185 goto free_list;
186 }
187
188 r = clist_append(list, str);
189 if (r < 0) {
190 free(str);
191 res = MAIL_ERROR_MEMORY;
192 goto free_list;
193 }
194 }
195
196 * result = list;
197
198 return MAIL_NO_ERROR;
199
200 free_list:
201 clist_foreach(list, (clist_func) free, NULL);
202 clist_free(list);
203 err:
204 return res;
205}
206
207static int generic_flags_read(MMAPString * mmapstr, size_t * index,
208 struct mail_flags ** result)
209{
210 clist * ext;
211 int r;
212 struct mail_flags * flags;
213 uint32_t value;
214 int res;
215
216 r = mailimf_cache_int_read(mmapstr, index, &value);
217 if (r != MAIL_NO_ERROR) {
218 res = r;
219 goto err;
220 }
221
222 r = flags_extension_read(mmapstr, index, &ext);
223 if (r != MAIL_NO_ERROR) {
224 res = r;
225 goto err;
226 }
227
228 flags = mail_flags_new(value, ext);
229 if (flags == NULL) {
230 res = r;
231 goto free;
232 }
233
234 * result = flags;
235
236 return MAIL_NO_ERROR;
237
238 free:
239 clist_foreach(ext, (clist_func) free, NULL);
240 clist_free(ext);
241 err:
242 return res;
243}
244
245static int flags_extension_write(MMAPString * mmapstr, size_t * index,
246 clist * ext)
247{
248 int r;
249 clistiter * cur;
250
251 r = mailimf_cache_int_write(mmapstr, index, clist_count(ext));
252 if (r != MAIL_NO_ERROR)
253 return r;
254
255 for(cur = clist_begin(ext) ; cur != NULL ; cur = clist_next(cur)) {
256 r = mailimf_cache_string_write(mmapstr, index,
257 clist_content(cur), strlen(clist_content(cur)));
258 if (r != MAIL_NO_ERROR)
259 return r;
260 }
261
262 return MAIL_NO_ERROR;
263}
264
265static int generic_flags_write(MMAPString * mmapstr, size_t * index,
266 struct mail_flags * flags)
267{
268 int r;
269
270 r = mailimf_cache_int_write(mmapstr, index,
271 flags->fl_flags & ~MAIL_FLAG_NEW);
272 if (r != MAIL_NO_ERROR)
273 return r;
274
275 r = flags_extension_write(mmapstr, index,
276 flags->fl_extension);
277 if (r != MAIL_NO_ERROR)
278 return r;
279
280 return MAIL_NO_ERROR;
281}
282
283
284
285
286static struct mail_flags * mail_flags_dup(struct mail_flags * flags)
287{
288 clist * list;
289 struct mail_flags * new_flags;
290 int r;
291 clistiter * cur;
292
293 list = clist_new();
294 if (list == NULL) {
295 goto err;
296 }
297
298 for(cur = clist_begin(flags->fl_extension) ; cur != NULL ;
299 cur = clist_next(cur)) {
300 char * ext;
301
302 ext = strdup(clist_content(cur));
303 if (ext == NULL) {
304 goto free;
305 }
306
307 r = clist_append(list, ext);
308 if (r < 0) {
309 free(ext);
310 goto free;
311 }
312 }
313
314 new_flags = mail_flags_new(flags->fl_flags, list);
315 if (new_flags == NULL) {
316 goto free;
317 }
318
319 return new_flags;
320
321 free:
322 clist_foreach(list, (clist_func) free, NULL);
323 clist_free(list);
324 err:
325 return NULL;
326}
327
328static mailmessage * mailmessage_build(mailmessage * msg)
329{
330 mailmessage * new_msg;
331
332 new_msg = malloc(sizeof(* new_msg));
333 if (new_msg == NULL)
334 goto err;
335
336 new_msg->msg_session = msg->msg_session;
337 new_msg->msg_driver = msg->msg_driver;
338 new_msg->msg_index = msg->msg_index;
339 if (msg->msg_uid == NULL)
340 new_msg->msg_uid = NULL;
341 else {
342 new_msg->msg_uid = strdup(msg->msg_uid);
343 if (new_msg->msg_uid == NULL)
344 goto free;
345 }
346
347 new_msg->msg_cached = msg->msg_cached;
348 new_msg->msg_size = msg->msg_size;
349 new_msg->msg_fields = NULL;
350 new_msg->msg_flags = mail_flags_dup(msg->msg_flags);
351 if (new_msg->msg_flags == NULL) {
352 free(new_msg->msg_uid);
353 goto free;
354 }
355
356 new_msg->msg_mime = NULL;
357 new_msg->msg_data = NULL;
358
359 return new_msg;
360
361 free:
362 free(new_msg);
363 err:
364 return NULL;
365}
366
367struct mail_flags_store * mail_flags_store_new(void)
368{
369 struct mail_flags_store * flags_store;
370
371 flags_store = malloc(sizeof(struct mail_flags_store));
372 if (flags_store == NULL)
373 goto err;
374
375 flags_store->fls_tab = carray_new(128);
376 if (flags_store->fls_tab == NULL)
377 goto free;
378
379 flags_store->fls_hash = chash_new(128, CHASH_COPYALL);
380 if (flags_store->fls_hash == NULL)
381 goto free_tab;
382
383 return flags_store;
384
385 free_tab:
386 carray_free(flags_store->fls_tab);
387 free:
388 free(flags_store);
389 err:
390 return NULL;
391}
392
393void mail_flags_store_clear(struct mail_flags_store * flags_store)
394{
395 unsigned int i;
396
397 for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
398 chashdatum key;
399 mailmessage * msg;
400
401 msg = carray_get(flags_store->fls_tab, i);
402
403 key.data = &msg->msg_index;
404 key.len = sizeof(msg->msg_index);
405 chash_delete(flags_store->fls_hash, &key, NULL);
406
407 mailmessage_free(msg);
408 }
409 carray_set_size(flags_store->fls_tab, 0);
410}
411
412void mail_flags_store_free(struct mail_flags_store * flags_store)
413{
414 mail_flags_store_clear(flags_store);
415 chash_free(flags_store->fls_hash);
416 carray_free(flags_store->fls_tab);
417 free(flags_store);
418}
419
420int mail_flags_store_set(struct mail_flags_store * flags_store,
421 mailmessage * msg)
422{
423 chashdatum key;
424 chashdatum value;
425 unsigned int index;
426 int res;
427 int r;
428 mailmessage * new_msg;
429
430 if (msg->msg_flags == NULL) {
431 res = MAIL_NO_ERROR;
432 goto err;
433 }
434
435 /* duplicate needed message info */
436 new_msg = mailmessage_build(msg);
437 if (new_msg == NULL) {
438 res = MAIL_ERROR_MEMORY;
439 goto err;
440 }
441
442 key.data = &new_msg->msg_index;
443 key.len = sizeof(new_msg->msg_index);
444
445 r = chash_get(flags_store->fls_hash, &key, &value);
446 if (r == 0) {
447 mailmessage * old_msg;
448
449 index = * (unsigned int *) value.data;
450 old_msg = carray_get(flags_store->fls_tab, index);
451 mailmessage_free(old_msg);
452 }
453 else {
454 r = carray_set_size(flags_store->fls_tab,
455 carray_count(flags_store->fls_tab) + 1);
456 if (r != 0) {
457 res = MAIL_ERROR_MEMORY;
458 goto err;
459 }
460 index = carray_count(flags_store->fls_tab) - 1;
461 }
462
463 carray_set(flags_store->fls_tab, index, new_msg);
464
465 value.data = &index;
466 value.len = sizeof(index);
467
468 r = chash_set(flags_store->fls_hash, &key, &value, NULL);
469 if (r < 0) {
470 carray_delete(flags_store->fls_tab, index);
471 res = MAIL_ERROR_MEMORY;
472 goto free;
473 }
474
475 return MAIL_NO_ERROR;
476
477 free:
478 mailmessage_free(new_msg);
479 err:
480 return res;
481}
482
483static int msg_index_compare(mailmessage ** msg1, mailmessage ** msg2)
484{
485 return (* msg1)->msg_index - (* msg2)->msg_index;
486}
487
488void mail_flags_store_sort(struct mail_flags_store * flags_store)
489{
490 qsort(carray_data(flags_store->fls_tab),
491 carray_count(flags_store->fls_tab), sizeof(mailmessage *),
492 (int (*)(const void *, const void *)) msg_index_compare);
493}
494
495struct mail_flags *
496mail_flags_store_get(struct mail_flags_store * flags_store, uint32_t index)
497{
498 struct mail_flags * flags;
499 chashdatum key;
500 chashdatum value;
501 int r;
502 unsigned int tab_index;
503 mailmessage * msg;
504
505 key.data = &index;
506 key.len = sizeof(index);
507
508 r = chash_get(flags_store->fls_hash, &key, &value);
509
510 if (r < 0)
511 return NULL;
512
513#if 0
514 flags = mail_flags_dup((struct mail_flags *) value.data);
515#endif
516 tab_index = * (unsigned int *) value.data;
517 msg = carray_get(flags_store->fls_tab, tab_index);
518 if (msg->msg_flags == NULL)
519 return NULL;
520
521 flags = mail_flags_dup(msg->msg_flags);
522
523 return flags;
524}
525
526int mail_flags_compare(struct mail_flags * flags1, struct mail_flags * flags2)
527{
528 clistiter * cur1;
529
530 if (clist_count(flags1->fl_extension) != clist_count(flags2->fl_extension))
531 return -1;
532
533 for(cur1 = clist_begin(flags1->fl_extension) ; cur1 != NULL ;
534 cur1 = clist_next(cur1)) {
535 char * flag1;
536 clistiter * cur2;
537 int found;
538
539 flag1 = clist_content(cur1);
540
541 found = 0;
542 for(cur2 = clist_begin(flags2->fl_extension) ; cur2 != NULL ;
543 cur2 = clist_next(cur2)) {
544 char * flag2;
545
546 flag2 = clist_content(cur2);
547
548 if (strcasecmp(flag1, flag2) == 0) {
549 found = 1;
550 break;
551 }
552 }
553
554 if (!found)
555 return -1;
556 }
557
558 return flags1->fl_flags - flags2->fl_flags;
559}
560
561
562int generic_cache_fields_read(struct mail_cache_db * cache_db,
563 MMAPString * mmapstr,
564 char * keyname, struct mailimf_fields ** result)
565{
566 int r;
567 int res;
568 size_t cur_token;
569 struct mailimf_fields * fields;
570 void * data;
571 size_t data_len;
572
573 r = mail_cache_db_get(cache_db, keyname, strlen(keyname), &data, &data_len);
574 if (r != 0) {
575 res = MAIL_ERROR_CACHE_MISS;
576 goto err;
577 }
578
579 r = mail_serialize_clear(mmapstr, &cur_token);
580 if (r != MAIL_NO_ERROR) {
581 res = r;
582 goto err;
583 }
584
585 if (mmap_string_append_len(mmapstr, data, data_len) == NULL) {
586 res = MAIL_ERROR_MEMORY;
587 goto err;
588 }
589
590 r = mailimf_cache_fields_read(mmapstr, &cur_token, &fields);
591 if (r != MAIL_NO_ERROR) {
592 res = r;
593 goto err;
594 }
595
596 * result = fields;
597
598 return MAIL_NO_ERROR;
599
600 err:
601 return res;
602}
603
604int generic_cache_fields_write(struct mail_cache_db * cache_db,
605 MMAPString * mmapstr,
606 char * keyname, struct mailimf_fields * fields)
607{
608 int r;
609 int res;
610 size_t cur_token;
611
612 r = mail_serialize_clear(mmapstr, &cur_token);
613 if (r != MAIL_NO_ERROR) {
614 res = r;
615 goto err;
616 }
617
618 r = mailimf_cache_fields_write(mmapstr, &cur_token, fields);
619 if (r != MAIL_NO_ERROR) {
620 res = r;
621 goto err;
622 }
623
624 r = mail_cache_db_put(cache_db, keyname, strlen(keyname),
625 mmapstr->str, mmapstr->len);
626 if (r != 0) {
627 res = MAIL_ERROR_FILE;
628 goto err;
629 }
630
631 return MAIL_NO_ERROR;
632
633 err:
634 return res;
635}
636
637int generic_cache_flags_read(struct mail_cache_db * cache_db,
638 MMAPString * mmapstr,
639 char * keyname, struct mail_flags ** result)
640{
641 int r;
642 int res;
643 size_t cur_token;
644 struct mail_flags * flags;
645 void * data;
646 size_t data_len;
647
648 r = mail_cache_db_get(cache_db, keyname, strlen(keyname), &data, &data_len);
649 if (r != 0) {
650 res = MAIL_ERROR_CACHE_MISS;
651 goto err;
652 }
653
654 r = mail_serialize_clear(mmapstr, &cur_token);
655 if (r != MAIL_NO_ERROR) {
656 res = r;
657 goto err;
658 }
659
660 if (mmap_string_append_len(mmapstr, data, data_len) == NULL) {
661 res = MAIL_ERROR_MEMORY;
662 goto err;
663 }
664
665 r = generic_flags_read(mmapstr, &cur_token, &flags);
666 if (r != MAIL_NO_ERROR) {
667 res = r;
668 goto err;
669 }
670
671 * result = flags;
672
673 return MAIL_NO_ERROR;
674
675 err:
676 return res;
677}
678
679int generic_cache_flags_write(struct mail_cache_db * cache_db,
680 MMAPString * mmapstr,
681 char * keyname, struct mail_flags * flags)
682{
683 int r;
684 int res;
685 size_t cur_token;
686
687 r = mail_serialize_clear(mmapstr, &cur_token);
688 if (r != MAIL_NO_ERROR) {
689 res = r;
690 goto err;
691 }
692
693 r = generic_flags_write(mmapstr, &cur_token, flags);
694 if (r != MAIL_NO_ERROR) {
695 res = r;
696 goto err;
697 }
698
699 r = mail_cache_db_put(cache_db, keyname, strlen(keyname),
700 mmapstr->str, mmapstr->len);
701 if (r != 0) {
702 res = MAIL_ERROR_FILE;
703 goto err;
704 }
705
706 return MAIL_NO_ERROR;
707
708 err:
709 return res;
710}
711
712
713int generic_cache_delete(struct mail_cache_db * cache_db,
714 char * keyname)
715{
716 int r;
717 int res;
718
719 r = mail_cache_db_del(cache_db, keyname, strlen(keyname));
720 if (r != 0) {
721 res = MAIL_ERROR_FILE;
722 goto err;
723 }
724
725 return MAIL_NO_ERROR;
726
727 err:
728 return res;
729}
diff --git a/kmicromail/libetpan/generic/generic_cache.h b/kmicromail/libetpan/generic/generic_cache.h
new file mode 100644
index 0000000..7815831
--- a/dev/null
+++ b/kmicromail/libetpan/generic/generic_cache.h
@@ -0,0 +1,109 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef GENERIC_CACHE_H
37
38#define GENERIC_CACHE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "generic_cache_types.h"
45#include "mailmessage_types.h"
46#include "chash.h"
47#include "carray.h"
48#include "mail_cache_db_types.h"
49
50int generic_cache_create_dir(char * dirname);
51
52int generic_cache_store(char * filename, char * content, size_t length);
53int generic_cache_read(char * filename, char ** result, size_t * result_len);
54
55int generic_cache_fields_read(struct mail_cache_db * cache_db,
56 MMAPString * mmapstr,
57 char * keyname, struct mailimf_fields ** result);
58
59int generic_cache_fields_write(struct mail_cache_db * cache_db,
60 MMAPString * mmapstr,
61 char * keyname, struct mailimf_fields * fields);
62
63int generic_cache_flags_read(struct mail_cache_db * cache_db,
64 MMAPString * mmapstr,
65 char * keyname, struct mail_flags ** result);
66
67int generic_cache_flags_write(struct mail_cache_db * cache_db,
68 MMAPString * mmapstr,
69 char * keyname, struct mail_flags * flags);
70
71int generic_cache_delete(struct mail_cache_db * cache_db, char * keyname);
72
73#if 0
74int generic_cache_fields_read(DB * dbp, MMAPString * mmapstr,
75 char * keyname, struct mailimf_fields ** result);
76
77int generic_cache_fields_write(DB * dbp, MMAPString * mmapstr,
78 char * keyname, struct mailimf_fields * fields);
79
80int generic_cache_flags_read(DB * dbp, MMAPString * mmapstr,
81 char * keyname, struct mail_flags ** result);
82
83int generic_cache_flags_write(DB * dbp, MMAPString * mmapstr,
84 char * keyname, struct mail_flags * flags);
85
86int generic_cache_delete(DB * dbp, char * keyname);
87#endif
88
89struct mail_flags_store * mail_flags_store_new(void);
90
91void mail_flags_store_clear(struct mail_flags_store * flags_store);
92
93void mail_flags_store_free(struct mail_flags_store * flags_store);
94
95int mail_flags_store_set(struct mail_flags_store * flags_store,
96 mailmessage * msg);
97
98void mail_flags_store_sort(struct mail_flags_store * flags_store);
99
100struct mail_flags *
101mail_flags_store_get(struct mail_flags_store * flags_store, uint32_t index);
102
103int mail_flags_compare(struct mail_flags * flags1, struct mail_flags * flags2);
104
105#ifdef __cplusplus
106}
107#endif
108
109#endif
diff --git a/kmicromail/libetpan/generic/generic_cache_types.h b/kmicromail/libetpan/generic/generic_cache_types.h
new file mode 100644
index 0000000..8803a42
--- a/dev/null
+++ b/kmicromail/libetpan/generic/generic_cache_types.h
@@ -0,0 +1,56 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef GENERIC_CACHE_TYPE_H
37
38#define GENERIC_CACHE_TYPE_H
39
40#include <libetpan/carray.h>
41#include <libetpan/chash.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47struct mail_flags_store {
48 carray * fls_tab;
49 chash * fls_hash;
50};
51
52#ifdef __cplusplus
53}
54#endif
55
56#endif
diff --git a/kmicromail/libetpan/generic/imapdriver.c b/kmicromail/libetpan/generic/imapdriver.c
new file mode 100644
index 0000000..0d63319
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver.c
@@ -0,0 +1,1130 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "imapdriver.h"
37
38#include "mail.h"
39#include "imapdriver_tools.h"
40#include "mailmessage.h"
41#include "imapdriver_message.h"
42#include "imapdriver_types.h"
43#include "maildriver.h"
44#include "maildriver_tools.h"
45#include "generic_cache.h"
46
47#include <stdlib.h>
48#include <string.h>
49
50static int imapdriver_initialize(mailsession * session);
51
52static void imapdriver_uninitialize(mailsession * session);
53
54static int imapdriver_connect_stream(mailsession * session, mailstream * s);
55
56static int imapdriver_starttls(mailsession * session);
57
58static int imapdriver_login(mailsession * session,
59 char * userid, char * password);
60
61static int imapdriver_logout(mailsession * session);
62
63static int imapdriver_noop(mailsession * session);
64
65static int imapdriver_build_folder_name(mailsession * session, char * mb,
66 char * name, char ** result);
67
68static int imapdriver_create_folder(mailsession * session, char * mb);
69
70static int imapdriver_delete_folder(mailsession * session, char * mb);
71
72static int imapdriver_rename_folder(mailsession * session, char * mb,
73 char * new_name);
74
75static int imapdriver_check_folder(mailsession * session);
76
77static int imapdriver_examine_folder(mailsession * session, char * mb);
78
79static int imapdriver_select_folder(mailsession * session, char * mb);
80static int imapdriver_expunge_folder(mailsession * session);
81
82static int imapdriver_status_folder(mailsession * session, char * mb,
83 uint32_t * result_messages, uint32_t * result_recent,
84 uint32_t * result_unseen);
85
86static int imapdriver_messages_number(mailsession * session, char * mb,
87 uint32_t * result);
88
89static int imapdriver_recent_number(mailsession * session, char * mb,
90 uint32_t * result);
91
92static int imapdriver_unseen_number(mailsession * session, char * mb,
93 uint32_t * result);
94
95static int imapdriver_list_folders(mailsession * session, char * mb,
96 struct mail_list ** result);
97static int imapdriver_lsub_folders(mailsession * session, char * mb,
98 struct mail_list ** result);
99static int imapdriver_subscribe_folder(mailsession * session, char * mb);
100static int imapdriver_unsubscribe_folder(mailsession * session, char * mb);
101static int imapdriver_append_message(mailsession * session,
102 char * message, size_t size);
103static int imapdriver_copy_message(mailsession * session,
104 uint32_t num, char * mb);
105
106static int imapdriver_get_messages_list(mailsession * session,
107 struct mailmessage_list ** result);
108
109static int
110imapdriver_get_envelopes_list(mailsession * session,
111 struct mailmessage_list * env_list);
112
113
114#if 0
115static int imapdriver_search_messages(mailsession * session, char * charset,
116 struct mail_search_key * key,
117 struct mail_search_result ** result);
118#endif
119
120static int imapdriver_get_message(mailsession * session,
121 uint32_t num, mailmessage ** result);
122
123static int imapdriver_get_message_by_uid(mailsession * session,
124 const char * uid,
125 mailmessage ** result);
126
127static mailsession_driver local_imap_session_driver = {
128 .sess_name = "imap",
129
130 .sess_initialize = imapdriver_initialize,
131 .sess_uninitialize = imapdriver_uninitialize,
132
133 .sess_parameters = NULL,
134
135 .sess_connect_stream = imapdriver_connect_stream,
136 .sess_connect_path = NULL,
137 .sess_starttls = imapdriver_starttls,
138 .sess_login = imapdriver_login,
139 .sess_logout = imapdriver_logout,
140 .sess_noop = imapdriver_noop,
141
142 .sess_build_folder_name = imapdriver_build_folder_name,
143 .sess_create_folder = imapdriver_create_folder,
144 .sess_delete_folder = imapdriver_delete_folder,
145 .sess_rename_folder = imapdriver_rename_folder,
146 .sess_check_folder = imapdriver_check_folder,
147 .sess_examine_folder = imapdriver_examine_folder,
148 .sess_select_folder = imapdriver_select_folder,
149 .sess_expunge_folder = imapdriver_expunge_folder,
150 .sess_status_folder = imapdriver_status_folder,
151 .sess_messages_number = imapdriver_messages_number,
152 .sess_recent_number = imapdriver_recent_number,
153 .sess_unseen_number = imapdriver_unseen_number,
154 .sess_list_folders = imapdriver_list_folders,
155 .sess_lsub_folders = imapdriver_lsub_folders,
156 .sess_subscribe_folder = imapdriver_subscribe_folder,
157 .sess_unsubscribe_folder = imapdriver_unsubscribe_folder,
158
159 .sess_append_message = imapdriver_append_message,
160 .sess_copy_message = imapdriver_copy_message,
161 .sess_move_message = NULL,
162
163 .sess_get_messages_list = imapdriver_get_messages_list,
164 .sess_get_envelopes_list = imapdriver_get_envelopes_list,
165 .sess_remove_message = NULL,
166#if 0
167 .sess_search_messages = imapdriver_search_messages,
168#endif
169
170 .sess_get_message = imapdriver_get_message,
171 .sess_get_message_by_uid = imapdriver_get_message_by_uid,
172};
173
174mailsession_driver * imap_session_driver = &local_imap_session_driver;
175
176static inline struct imap_session_state_data * get_data(mailsession * session)
177{
178 return session->sess_data;
179}
180
181static mailimap * get_imap_session(mailsession * session)
182{
183 return get_data(session)->imap_session;
184}
185
186static int imapdriver_initialize(mailsession * session)
187{
188 struct imap_session_state_data * data;
189 mailimap * imap;
190 struct mail_flags_store * flags_store;
191
192 imap = mailimap_new(0, NULL);
193 if (imap == NULL)
194 goto err;
195
196 flags_store = mail_flags_store_new();
197 if (flags_store == NULL)
198 goto free_session;
199
200 data = malloc(sizeof(* data));
201 if (data == NULL)
202 goto free_flags_store;
203
204 data->imap_mailbox = NULL;
205 data->imap_session = imap;
206 data->imap_flags_store = flags_store;
207
208 session->sess_data = data;
209
210 return MAIL_NO_ERROR;
211
212 free_flags_store:
213 mail_flags_store_free(flags_store);
214 free_session:
215 mailimap_free(imap);
216 err:
217 return MAIL_ERROR_MEMORY;
218}
219
220static void imap_flags_store_process(mailimap * imap,
221 struct mail_flags_store * flags_store)
222{
223 unsigned int i;
224 int r;
225 mailmessage * first;
226 mailmessage * last;
227
228 mail_flags_store_sort(flags_store);
229
230 if (carray_count(flags_store->fls_tab) == 0)
231 return;
232
233 first = carray_get(flags_store->fls_tab, 0);
234 last = first;
235
236 for(i = 1 ; i < carray_count(flags_store->fls_tab) ; i ++) {
237 mailmessage * msg;
238
239 msg = carray_get(flags_store->fls_tab, i);
240
241 if (last->msg_index + 1 == msg->msg_index) {
242 r = mail_flags_compare(first->msg_flags, msg->msg_flags);
243 if (r == 0) {
244 last = msg;
245 continue;
246 }
247 }
248
249 r = imap_store_flags(imap, first->msg_index,
250 last->msg_index, first->msg_flags);
251
252 first = msg;
253 last = msg;
254 }
255
256 r = imap_store_flags(imap, first->msg_index, last->msg_index,
257 first->msg_flags);
258
259 mail_flags_store_clear(flags_store);
260}
261
262static void imapdriver_uninitialize(mailsession * session)
263{
264 struct imap_session_state_data * data;
265
266 data = get_data(session);
267
268 imap_flags_store_process(data->imap_session,
269 data->imap_flags_store);
270 mail_flags_store_free(data->imap_flags_store);
271
272 mailimap_free(data->imap_session);
273 if (data->imap_mailbox != NULL)
274 free(data->imap_mailbox);
275 free(data);
276
277 session->sess_data = NULL;
278}
279
280static int imapdriver_connect_stream(mailsession * session, mailstream * s)
281{
282 int r;
283
284 r = mailimap_connect(get_imap_session(session), s);
285
286 return imap_error_to_mail_error(r);
287}
288
289static int imapdriver_login(mailsession * session,
290 char * userid, char * password)
291{
292 int r;
293
294 r = mailimap_login(get_imap_session(session), userid, password);
295
296 return imap_error_to_mail_error(r);
297}
298
299static int imapdriver_logout(mailsession * session)
300{
301 int r;
302
303 imap_flags_store_process(get_imap_session(session),
304 get_data(session)->imap_flags_store);
305
306 r = mailimap_logout(get_imap_session(session));
307
308 return imap_error_to_mail_error(r);
309}
310
311static int imapdriver_noop(mailsession * session)
312{
313 int r;
314
315 r = mailimap_noop(get_imap_session(session));
316
317 return imap_error_to_mail_error(r);
318}
319
320static int imapdriver_build_folder_name(mailsession * session, char * mb,
321 char * name, char ** result)
322{
323 char delimiter[2] = "X";
324 char * folder_name;
325 mailimap * imap;
326 struct mailimap_mailbox_list * mb_list;
327 int r;
328 clist * imap_list;
329
330 imap = get_imap_session(session);
331
332 r = mailimap_list(imap, mb, "", &imap_list);
333 if (r != MAILIMAP_NO_ERROR)
334 return r;
335
336 if (clist_begin(imap_list) == NULL)
337 return MAIL_ERROR_LIST;
338
339 mb_list = clist_begin(imap_list)->data;
340 delimiter[0] = mb_list->mb_delimiter;
341
342 folder_name = malloc(strlen(mb) + strlen(delimiter) + strlen(name) + 1);
343 if (folder_name == NULL)
344 return MAIL_ERROR_MEMORY;
345
346 strcpy(folder_name, mb);
347 strcat(folder_name, delimiter);
348 strcat(folder_name, name);
349
350 * result = folder_name;
351
352 return MAIL_NO_ERROR;
353}
354
355/* folders operations */
356
357static int imapdriver_create_folder(mailsession * session, char * mb)
358{
359 int r;
360
361 r = mailimap_create(get_imap_session(session), mb);
362
363 return imap_error_to_mail_error(r);
364}
365
366static int imapdriver_delete_folder(mailsession * session, char * mb)
367{
368 int r;
369
370 r = mailimap_delete(get_imap_session(session), mb);
371
372 return imap_error_to_mail_error(r);
373}
374
375static int imapdriver_rename_folder(mailsession * session, char * mb,
376 char * new_name)
377{
378 int r;
379
380 r = mailimap_rename(get_imap_session(session), mb, new_name);
381
382 return imap_error_to_mail_error(r);
383}
384
385static int imapdriver_check_folder(mailsession * session)
386{
387 int r;
388
389 imap_flags_store_process(get_imap_session(session),
390 get_data(session)->imap_flags_store);
391
392 r = mailimap_check(get_imap_session(session));
393
394 return imap_error_to_mail_error(r);
395}
396
397static int imapdriver_examine_folder(mailsession * session, char * mb)
398{
399 int r;
400
401 r = mailimap_examine(get_imap_session(session), mb);
402
403 return imap_error_to_mail_error(r);
404}
405
406static int imapdriver_select_folder(mailsession * session, char * mb)
407{
408 int r;
409 char * new_mb;
410 char * old_mb;
411
412 old_mb = get_data(session)->imap_mailbox;
413 if (old_mb != NULL)
414 if (strcmp(mb, old_mb) == 0)
415 return MAIL_NO_ERROR;
416
417 imap_flags_store_process(get_imap_session(session),
418 get_data(session)->imap_flags_store);
419
420 r = mailimap_select(get_imap_session(session), mb);
421
422 switch (r) {
423 case MAILIMAP_NO_ERROR:
424 new_mb = strdup(mb);
425 if (new_mb == NULL) {
426 if (old_mb != NULL)
427 free(old_mb);
428 get_data(session)->imap_mailbox = NULL;
429 return MAIL_ERROR_MEMORY;
430 }
431
432 get_data(session)->imap_mailbox = new_mb;
433
434 return MAIL_NO_ERROR;
435 default:
436 return imap_error_to_mail_error(r);
437 }
438}
439
440static int imapdriver_expunge_folder(mailsession * session)
441{
442 int r;
443
444 imap_flags_store_process(get_imap_session(session),
445 get_data(session)->imap_flags_store);
446
447 r = mailimap_expunge(get_imap_session(session));
448
449 return imap_error_to_mail_error(r);
450}
451
452static int status_selected_folder(mailsession * session, char * mb,
453 uint32_t * result_messages, uint32_t * result_recent,
454 uint32_t * result_unseen)
455{
456 int r;
457 int res;
458 mailimap * imap;
459 uint32_t exists;
460 uint32_t unseen;
461 uint32_t recent;
462 struct mailimap_search_key * search_key;
463 clist * search_result;
464
465 imap = get_imap_session(session);
466
467 exists = imap->imap_selection_info->sel_exists;
468 recent = imap->imap_selection_info->sel_recent;
469
470 search_key = mailimap_search_key_new(MAILIMAP_SEARCH_KEY_UNSEEN,
471 NULL, NULL, NULL, NULL, NULL,
472 NULL, NULL, NULL, NULL, NULL,
473 NULL, NULL, NULL, NULL, 0,
474 NULL, NULL, NULL, NULL, NULL,
475 NULL, 0, NULL, NULL, NULL);
476 if (search_key == NULL) {
477 res = MAIL_ERROR_MEMORY;
478 goto err;
479 }
480
481 /* default : use the RECENT count if search fails */
482 unseen = recent;
483 r = mailimap_search(imap, NULL, search_key, &search_result);
484 mailimap_search_key_free(search_key);
485 if (r == MAILIMAP_NO_ERROR) {
486 /* if this succeed, we use the real count */
487 unseen = clist_count(search_result);
488 mailimap_mailbox_data_search_free(search_result);
489 }
490
491 * result_messages = exists;
492 * result_unseen = unseen;
493 * result_recent = recent;
494
495 return MAIL_NO_ERROR;
496
497 err:
498 return res;
499}
500
501static int status_unselected_folder(mailsession * session, char * mb,
502 uint32_t * result_messages, uint32_t * result_recent,
503 uint32_t * result_unseen)
504{
505 struct mailimap_status_att_list * att_list;
506 struct mailimap_mailbox_data_status * status;
507 int r;
508 int res;
509 clistiter * cur;
510 mailimap * imap;
511
512 imap = get_imap_session(session);
513
514 att_list = mailimap_status_att_list_new_empty();
515 if (att_list == NULL) {
516 res = MAIL_ERROR_MEMORY;
517 goto err;
518 }
519
520 r = mailimap_status_att_list_add(att_list, MAILIMAP_STATUS_ATT_MESSAGES);
521 switch (r) {
522 case MAILIMAP_NO_ERROR:
523 break;
524 default:
525 res = MAIL_ERROR_MEMORY;
526 goto free;
527 }
528
529 r = mailimap_status_att_list_add(att_list, MAILIMAP_STATUS_ATT_RECENT);
530 switch (r) {
531 case MAILIMAP_NO_ERROR:
532 break;
533 default:
534 res = MAIL_ERROR_MEMORY;
535 goto free;
536 }
537
538 r = mailimap_status_att_list_add(att_list, MAILIMAP_STATUS_ATT_UNSEEN);
539 switch (r) {
540 case MAILIMAP_NO_ERROR:
541 break;
542 default:
543 res = MAIL_ERROR_MEMORY;
544 goto free;
545 }
546
547 r = mailimap_status(imap, mb, att_list, &status);
548
549 switch (r) {
550 case MAILIMAP_NO_ERROR:
551 break;
552 default:
553 res = imap_error_to_mail_error(r);
554 goto free;
555 }
556
557 * result_messages = 0;
558 * result_recent = 0;
559 * result_unseen = 0;
560
561 for (cur = clist_begin(status->st_info_list);
562 cur != NULL ; cur = clist_next(cur)) {
563 struct mailimap_status_info * status_info;
564
565 status_info = clist_content(cur);
566 switch (status_info->st_att) {
567 case MAILIMAP_STATUS_ATT_MESSAGES:
568 * result_messages = status_info->st_value;
569 break;
570 case MAILIMAP_STATUS_ATT_RECENT:
571 * result_recent = status_info->st_value;
572 break;
573 case MAILIMAP_STATUS_ATT_UNSEEN:
574 * result_unseen = status_info->st_value;
575 break;
576 }
577 }
578
579 mailimap_mailbox_data_status_free(status);
580 mailimap_status_att_list_free(att_list);
581
582 return MAIL_NO_ERROR;
583
584 free:
585 mailimap_status_att_list_free(att_list);
586 err:
587 return res;
588}
589
590static int imapdriver_status_folder(mailsession * session, char * mb,
591 uint32_t * result_messages, uint32_t * result_recent,
592 uint32_t * result_unseen)
593{
594 int res;
595 int current_folder;
596 char * current_mb;
597
598 if (mb == NULL) {
599 mb = get_data(session)->imap_mailbox;
600 if (mb == NULL) {
601 res = MAIL_ERROR_BAD_STATE;
602 goto err;
603 }
604 }
605
606 current_mb = get_data(session)->imap_mailbox;
607 if (strcmp(mb, current_mb) == 0)
608 current_folder = 1;
609 else
610 current_folder = 0;
611
612 if (current_folder)
613 return status_selected_folder(session, mb, result_messages,
614 result_recent, result_unseen);
615 else
616 return status_unselected_folder(session, mb, result_messages,
617 result_recent, result_unseen);
618
619 err:
620 return res;
621}
622
623/* TODO : more efficient functions */
624
625static int imapdriver_messages_number(mailsession * session, char * mb,
626 uint32_t * result)
627{
628 uint32_t messages;
629 uint32_t recent;
630 uint32_t unseen;
631 int r;
632
633 r = imapdriver_status_folder(session, mb, &messages, &recent, &unseen);
634 if (r != MAIL_NO_ERROR)
635 return r;
636
637 * result = messages;
638
639 return MAIL_NO_ERROR;
640}
641
642static int imapdriver_recent_number(mailsession * session, char * mb,
643 uint32_t * result)
644{
645 uint32_t messages;
646 uint32_t recent;
647 uint32_t unseen;
648 int r;
649
650 r = imapdriver_status_folder(session, mb, &messages, &recent, &unseen);
651 if (r != MAIL_NO_ERROR)
652 return r;
653
654 * result = recent;
655
656 return MAIL_NO_ERROR;
657}
658
659static int imapdriver_unseen_number(mailsession * session, char * mb,
660 uint32_t * result)
661{
662 uint32_t messages;
663 uint32_t recent;
664 uint32_t unseen;
665 int r;
666
667 r = imapdriver_status_folder(session, mb, &messages, &recent, &unseen);
668 if (r != MAIL_NO_ERROR)
669 return r;
670
671 * result = unseen;
672
673 return MAIL_NO_ERROR;
674}
675
676enum {
677 IMAP_LIST, IMAP_LSUB
678};
679
680static int imapdriver_list_lsub_folders(mailsession * session, int type,
681 char * mb,
682 struct mail_list ** result)
683{
684 clist * imap_list;
685 struct mail_list * resp;
686 int r;
687 int res;
688
689 switch (type) {
690 case IMAP_LIST:
691 r = mailimap_list(get_imap_session(session), mb,
692 "*", &imap_list);
693 break;
694 case IMAP_LSUB:
695 r = mailimap_lsub(get_imap_session(session), mb,
696 "*", &imap_list);
697 break;
698 default:
699 res = MAIL_ERROR_LIST;
700 goto err;
701 }
702
703 switch (r) {
704 case MAILIMAP_NO_ERROR:
705 break;
706 default:
707 res = imap_error_to_mail_error(r);
708 goto err;
709 }
710
711 r = imap_list_to_list(imap_list, &resp);
712 if (r != MAIL_NO_ERROR) {
713 mailimap_list_result_free(imap_list);
714 res = r;
715 goto err;
716 }
717
718 mailimap_list_result_free(imap_list);
719
720 * result = resp;
721
722 return MAIL_NO_ERROR;
723
724 err:
725 return res;
726}
727
728static int imapdriver_list_folders(mailsession * session, char * mb,
729 struct mail_list ** result)
730{
731 return imapdriver_list_lsub_folders(session, IMAP_LIST, mb,
732 result);
733}
734
735static int imapdriver_lsub_folders(mailsession * session, char * mb,
736 struct mail_list ** result)
737{
738 return imapdriver_list_lsub_folders(session, IMAP_LSUB, mb,
739 result);
740}
741
742static int imapdriver_subscribe_folder(mailsession * session, char * mb)
743{
744 int r;
745
746 r = mailimap_subscribe(get_imap_session(session), mb);
747
748 return imap_error_to_mail_error(r);
749}
750
751static int imapdriver_unsubscribe_folder(mailsession * session, char * mb)
752{
753 int r;
754
755 r = mailimap_unsubscribe(get_imap_session(session), mb);
756
757 return imap_error_to_mail_error(r);
758}
759
760/* messages operations */
761
762static int imapdriver_append_message(mailsession * session,
763 char * message, size_t size)
764{
765 int r;
766
767 r = mailimap_append_simple(get_imap_session(session),
768 get_data(session)->imap_mailbox,
769 message, size);
770
771 return imap_error_to_mail_error(r);
772}
773
774static int imapdriver_copy_message(mailsession * session,
775 uint32_t num, char * mb)
776{
777 int r;
778 struct mailimap_set * set;
779 int res;
780
781 set = mailimap_set_new_single(num);
782 if (set == NULL) {
783 res = MAIL_ERROR_MEMORY;
784 goto err;
785 }
786
787 r = mailimap_uid_copy(get_imap_session(session), set, mb);
788
789 mailimap_set_free(set);
790
791 return imap_error_to_mail_error(r);
792
793 err:
794 return res;
795}
796
797static int imapdriver_get_messages_list(mailsession * session,
798 struct mailmessage_list ** result)
799{
800 return imap_get_messages_list(get_imap_session(session),
801 session, imap_message_driver, 1,
802 result);
803}
804
805
806
807static int
808imapdriver_get_envelopes_list(mailsession * session,
809 struct mailmessage_list * env_list)
810{
811 struct mailimap_set * set;
812 struct mailimap_fetch_att * fetch_att;
813 struct mailimap_fetch_type * fetch_type;
814 int res;
815 clist * fetch_result;
816 int r;
817 uint32_t exists;
818 clist * msg_list;
819
820 if (get_imap_session(session)->imap_selection_info == NULL) {
821 res = MAIL_ERROR_BAD_STATE;
822 goto err;
823 }
824
825 imap_flags_store_process(get_imap_session(session),
826 get_data(session)->imap_flags_store);
827
828 exists = get_imap_session(session)->imap_selection_info->sel_exists;
829
830 if (exists == 0)
831 return MAIL_NO_ERROR;
832
833 fetch_type = mailimap_fetch_type_new_fetch_att_list_empty();
834 if (fetch_type == NULL) {
835 res = MAIL_ERROR_MEMORY;
836 goto err;
837 }
838
839 fetch_att = mailimap_fetch_att_new_uid();
840 if (fetch_att == NULL) {
841 res = MAIL_ERROR_MEMORY;
842 goto free_fetch_type;
843 }
844
845 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
846 if (r != MAILIMAP_NO_ERROR) {
847 mailimap_fetch_att_free(fetch_att);
848 res = MAIL_ERROR_MEMORY;
849 goto free_fetch_type;
850 }
851
852 fetch_att = mailimap_fetch_att_new_flags();
853 if (fetch_att == NULL) {
854 res = MAIL_ERROR_MEMORY;
855 goto free_fetch_type;
856 }
857
858 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
859 if (r != MAILIMAP_NO_ERROR) {
860 mailimap_fetch_att_free(fetch_att);
861 res = MAIL_ERROR_MEMORY;
862 goto free_fetch_type;
863 }
864
865 r = imap_add_envelope_fetch_att(fetch_type);
866 if (r != MAIL_NO_ERROR) {
867 res = r;
868 goto free_fetch_type;
869 }
870
871 r = maildriver_env_list_to_msg_list(env_list, &msg_list);
872 if (r != MAIL_NO_ERROR) {
873 res = MAIL_ERROR_MEMORY;
874 goto free_fetch_type;
875 }
876
877 if (clist_begin(msg_list) == NULL) {
878 /* no need to fetch envelopes */
879
880 mailimap_fetch_type_free(fetch_type);
881 clist_free(msg_list);
882 return MAIL_NO_ERROR;
883 }
884
885 r = msg_list_to_imap_set(msg_list, &set);
886 if (r != MAIL_NO_ERROR) {
887 clist_foreach(msg_list, (clist_func) free, NULL);
888 clist_free(msg_list);
889 res = MAIL_ERROR_MEMORY;
890 goto free_fetch_type;
891 }
892 clist_foreach(msg_list, (clist_func) free, NULL);
893 clist_free(msg_list);
894
895 r = mailimap_uid_fetch(get_imap_session(session), set,
896 fetch_type, &fetch_result);
897
898 mailimap_fetch_type_free(fetch_type);
899 mailimap_set_free(set);
900
901 switch (r) {
902 case MAILIMAP_NO_ERROR:
903 break;
904 default:
905 return imap_error_to_mail_error(r);
906 }
907
908 if (clist_begin(fetch_result) == NULL) {
909 res = MAIL_ERROR_FETCH;
910 goto err;
911 }
912
913 r = imap_fetch_result_to_envelop_list(fetch_result, env_list);
914 mailimap_fetch_list_free(fetch_result);
915
916 if (r != MAIL_NO_ERROR) {
917 res = MAIL_ERROR_MEMORY;
918 goto err;
919 }
920
921 return MAIL_NO_ERROR;
922
923 free_fetch_type:
924 mailimap_fetch_type_free(fetch_type);
925 err:
926 return res;
927}
928
929
930#if 0
931static int imapdriver_search_messages(mailsession * session, char * charset,
932 struct mail_search_key * key,
933 struct mail_search_result ** result)
934{
935 struct mailimap_search_key * imap_key;
936 int r;
937 clist * imap_result;
938 clist * result_list;
939 struct mail_search_result * search_result;
940 clistiter * cur;
941
942 r = mail_search_to_imap_search(key, &imap_key);
943 if (r != MAIL_NO_ERROR)
944 return MAIL_ERROR_MEMORY;
945
946 r = mailimap_uid_search(get_imap_session(session), charset, imap_key,
947 &imap_result);
948
949 mailimap_search_key_free(imap_key);
950
951 switch (r) {
952 case MAILIMAP_NO_ERROR:
953 break;
954 default:
955 return imap_error_to_mail_error(r);
956 }
957
958 result_list = clist_new();
959 if (result_list == NULL)
960 return MAIL_ERROR_MEMORY;
961
962 for(cur = clist_begin(imap_result) ; cur != NULL ; cur = clist_next(cur)) {
963 uint32_t val = * (uint32_t *) clist_content(cur);
964 uint32_t * new;
965
966 new = malloc(sizeof(* new));
967 if (new == NULL) {
968 goto free_imap_result;
969 }
970
971 * new = val;
972
973 r = clist_append(result_list, new);
974 if (r != 0) {
975 free(new);
976 goto free_imap_result;
977 }
978 }
979
980 search_result = mail_search_result_new(result_list);
981 if (search_result == NULL)
982 goto free_imap_result;
983
984 mailimap_search_result_free(imap_result);
985
986 * result = search_result;
987
988 return MAIL_NO_ERROR;
989
990 free_imap_result:
991 mailimap_search_result_free(imap_result);
992 return MAIL_ERROR_MEMORY;
993}
994#endif
995
996static int imapdriver_starttls(mailsession * session)
997{
998 mailimap * imap;
999 int r;
1000 struct mailimap_capability_data * cap_data;
1001 clistiter * cur;
1002 int starttls;
1003 int fd;
1004 mailstream_low * low;
1005 mailstream_low * new_low;
1006 int capability_available;
1007
1008 imap = get_imap_session(session);
1009
1010 capability_available = FALSE;
1011 if (imap->imap_connection_info != NULL)
1012 if (imap->imap_connection_info->imap_capability != NULL) {
1013 capability_available = TRUE;
1014 cap_data = imap->imap_connection_info->imap_capability;
1015 }
1016
1017 if (!capability_available) {
1018 r = mailimap_capability(imap, &cap_data);
1019 switch (r) {
1020 case MAILIMAP_NO_ERROR:
1021 break;
1022 default:
1023 return imap_error_to_mail_error(r);
1024 }
1025 }
1026
1027 starttls = FALSE;
1028 for(cur = clist_begin(cap_data->cap_list) ; cur != NULL ;
1029 cur = clist_next(cur)) {
1030 struct mailimap_capability * cap;
1031
1032 cap = clist_content(cur);
1033
1034 if (cap->cap_type == MAILIMAP_CAPABILITY_NAME)
1035 if (strcasecmp(cap->cap_data.cap_name, "STARTTLS") == 0) {
1036 starttls = TRUE;
1037 break;
1038 }
1039 }
1040
1041 if (!capability_available)
1042 mailimap_capability_data_free(cap_data);
1043
1044 if (!starttls)
1045 return MAIL_ERROR_NO_TLS;
1046
1047 r = mailimap_starttls(imap);
1048
1049 switch (r) {
1050 case MAILIMAP_NO_ERROR:
1051 break;
1052 default:
1053 return imap_error_to_mail_error(r);
1054 }
1055
1056 low = mailstream_get_low(imap->imap_stream);
1057 fd = mailstream_low_get_fd(low);
1058 if (fd == -1)
1059 return MAIL_ERROR_STREAM;
1060
1061 new_low = mailstream_low_ssl_open(fd);
1062 if (new_low == NULL)
1063 return MAIL_ERROR_STREAM;
1064
1065 mailstream_low_free(low);
1066 mailstream_set_low(imap->imap_stream, new_low);
1067
1068 return MAIL_NO_ERROR;
1069}
1070
1071static int imapdriver_get_message(mailsession * session,
1072 uint32_t num, mailmessage ** result)
1073{
1074 mailmessage * msg_info;
1075 int r;
1076
1077 msg_info = mailmessage_new();
1078 if (msg_info == NULL)
1079 return MAIL_ERROR_MEMORY;
1080
1081 r = mailmessage_init(msg_info, session, imap_message_driver, num, 0);
1082 if (r != MAIL_NO_ERROR) {
1083 mailmessage_free(msg_info);
1084 return r;
1085 }
1086
1087 * result = msg_info;
1088
1089 return MAIL_NO_ERROR;
1090}
1091
1092/* Retrieve a message by UID
1093
1094 libEtPan! uid format for IMAP is "UIDVALIDITY-UID"
1095 where UIDVALIDITY and UID are decimal representation of
1096 respectively uidvalidity and uid numbers.
1097
1098 Return value:
1099 MAIL_ERROR_INVAL if uid is NULL or has an incorrect format.
1100 MAIL_ERROR_MSG_NOT_FOUND if uidvalidity has changed or uid was not found
1101 MAIL_NO_ERROR if message was found. Result is in result
1102*/
1103
1104static int imapdriver_get_message_by_uid(mailsession * session,
1105 const char * uid,
1106 mailmessage ** result)
1107{
1108 uint32_t uidvalidity;
1109 uint32_t num;
1110 char * p1, * p2;
1111 mailimap * imap;
1112
1113 if (uid == NULL)
1114 return MAIL_ERROR_INVAL;
1115
1116 uidvalidity = strtoul(uid, &p1, 10);
1117 if (p1 == uid || * p1 != '-')
1118 return MAIL_ERROR_INVAL;
1119
1120 p1++;
1121 num = strtoul(p1, &p2, 10);
1122 if (p2 == p1 || * p2 != '\0')
1123 return MAIL_ERROR_INVAL;
1124
1125 imap = get_imap_session(session);
1126 if (imap->imap_selection_info->sel_uidvalidity != uidvalidity)
1127 return MAIL_ERROR_MSG_NOT_FOUND;
1128
1129 return imapdriver_get_message(session, num, result);
1130}
diff --git a/kmicromail/libetpan/generic/imapdriver.h b/kmicromail/libetpan/generic/imapdriver.h
new file mode 100644
index 0000000..2bf36c7
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef IMAPDRIVER_H
37
38#define IMAPDRIVER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/imapdriver_types.h>
45
46extern mailsession_driver * imap_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/imapdriver_cached.c b/kmicromail/libetpan/generic/imapdriver_cached.c
new file mode 100644
index 0000000..e6af8e8
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_cached.c
@@ -0,0 +1,1274 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "imapdriver_cached.h"
37
38#include "libetpan-config.h"
39
40#include <stdio.h>
41#include <sys/types.h>
42#include <sys/stat.h>
43#include <fcntl.h>
44#include <string.h>
45#include <unistd.h>
46#include <stdlib.h>
47
48#include "mail.h"
49#include "imapdriver_tools.h"
50#include "mail_cache_db.h"
51#include "mailmessage.h"
52#include "imapdriver_cached_message.h"
53#include "maildriver.h"
54#include "imapdriver_types.h"
55#include "generic_cache.h"
56#include "imfcache.h"
57#include "maildriver_tools.h"
58#include "imapdriver.h"
59
60static int imapdriver_cached_initialize(mailsession * session);
61static void imapdriver_cached_uninitialize(mailsession * session);
62
63static int imapdriver_cached_parameters(mailsession * session,
64 int id, void * value);
65
66static int imapdriver_cached_connect_stream(mailsession * session,
67 mailstream * s);
68
69static int imapdriver_cached_starttls(mailsession * session);
70
71static int imapdriver_cached_login(mailsession * session,
72 char * userid, char * password);
73static int imapdriver_cached_logout(mailsession * session);
74static int imapdriver_cached_noop(mailsession * session);
75static int imapdriver_cached_build_folder_name(mailsession * session,
76 char * mb,
77 char * name, char ** result);
78static int imapdriver_cached_create_folder(mailsession * session, char * mb);
79static int imapdriver_cached_delete_folder(mailsession * session, char * mb);
80static int imapdriver_cached_rename_folder(mailsession * session, char * mb,
81 char * new_name);
82static int imapdriver_cached_check_folder(mailsession * session);
83static int imapdriver_cached_examine_folder(mailsession * session,
84 char * mb);
85static int imapdriver_cached_select_folder(mailsession * session, char * mb);
86static int imapdriver_cached_expunge_folder(mailsession * session);
87static int imapdriver_cached_status_folder(mailsession * session, char * mb,
88 uint32_t * result_messages,
89 uint32_t * result_recent,
90 uint32_t * result_unseen);
91static int imapdriver_cached_messages_number(mailsession * session,
92 char * mb,
93 uint32_t * result);
94static int imapdriver_cached_recent_number(mailsession * session, char * mb,
95 uint32_t * result);
96static int imapdriver_cached_unseen_number(mailsession * session, char * mb,
97 uint32_t * result);
98static int imapdriver_cached_list_folders(mailsession * session, char * mb,
99 struct mail_list ** result);
100static int imapdriver_cached_lsub_folders(mailsession * session, char * mb,
101 struct mail_list ** result);
102static int imapdriver_cached_subscribe_folder(mailsession * session,
103 char * mb);
104static int imapdriver_cached_unsubscribe_folder(mailsession * session,
105 char * mb);
106static int imapdriver_cached_append_message(mailsession * session,
107 char * message, size_t size);
108static int imapdriver_cached_copy_message(mailsession * session,
109 uint32_t num, char * mb);
110
111static int imapdriver_cached_get_messages_list(mailsession * session,
112 struct mailmessage_list **
113 result);
114static int
115imapdriver_cached_get_envelopes_list(mailsession * session,
116 struct mailmessage_list * env_list);
117static int imapdriver_cached_remove_message(mailsession * session,
118 uint32_t num);
119
120#if 0
121static int imapdriver_cached_search_messages(mailsession * session,
122 char * charset,
123 struct mail_search_key * key,
124 struct mail_search_result **
125 result);
126#endif
127
128static int imapdriver_cached_get_message(mailsession * session,
129 uint32_t num, mailmessage ** result);
130
131static int imapdriver_cached_get_message_by_uid(mailsession * session,
132 const char * uid,
133 mailmessage ** result);
134
135static mailsession_driver local_imap_cached_session_driver = {
136 .sess_name = "imap-cached",
137
138 .sess_initialize = imapdriver_cached_initialize,
139 .sess_uninitialize = imapdriver_cached_uninitialize,
140
141 .sess_parameters = imapdriver_cached_parameters,
142
143 .sess_connect_stream = imapdriver_cached_connect_stream,
144 .sess_connect_path = NULL,
145 .sess_starttls = imapdriver_cached_starttls,
146 .sess_login = imapdriver_cached_login,
147 .sess_logout = imapdriver_cached_logout,
148 .sess_noop = imapdriver_cached_noop,
149
150 .sess_build_folder_name = imapdriver_cached_build_folder_name,
151 .sess_create_folder = imapdriver_cached_create_folder,
152 .sess_delete_folder = imapdriver_cached_delete_folder,
153 .sess_rename_folder = imapdriver_cached_rename_folder,
154 .sess_check_folder = imapdriver_cached_check_folder,
155 .sess_examine_folder = imapdriver_cached_examine_folder,
156 .sess_select_folder = imapdriver_cached_select_folder,
157 .sess_expunge_folder = imapdriver_cached_expunge_folder,
158 .sess_status_folder = imapdriver_cached_status_folder,
159 .sess_messages_number = imapdriver_cached_messages_number,
160 .sess_recent_number = imapdriver_cached_recent_number,
161 .sess_unseen_number = imapdriver_cached_unseen_number,
162 .sess_list_folders = imapdriver_cached_list_folders,
163 .sess_lsub_folders = imapdriver_cached_lsub_folders,
164 .sess_subscribe_folder = imapdriver_cached_subscribe_folder,
165 .sess_unsubscribe_folder = imapdriver_cached_unsubscribe_folder,
166
167 .sess_append_message = imapdriver_cached_append_message,
168 .sess_copy_message = imapdriver_cached_copy_message,
169 .sess_move_message = NULL,
170
171 .sess_get_messages_list = imapdriver_cached_get_messages_list,
172 .sess_get_envelopes_list = imapdriver_cached_get_envelopes_list,
173 .sess_remove_message = imapdriver_cached_remove_message,
174#if 0
175 .sess_search_messages = imapdriver_cached_search_messages,
176#endif
177
178 .sess_get_message = imapdriver_cached_get_message,
179 .sess_get_message_by_uid = imapdriver_cached_get_message_by_uid,
180};
181
182mailsession_driver * imap_cached_session_driver =
183&local_imap_cached_session_driver;
184
185#define CACHE_MESSAGE_LIST
186
187static inline struct imap_cached_session_state_data *
188get_cached_data(mailsession * session)
189{
190 return session->sess_data;
191}
192
193static inline mailsession * get_ancestor(mailsession * s)
194{
195 return get_cached_data(s)->imap_ancestor;
196}
197
198static inline
199struct imap_session_state_data * get_ancestor_data(mailsession * s)
200{
201 return get_ancestor(s)->sess_data;
202}
203
204static inline mailimap * get_imap_session(mailsession * session)
205{
206 return get_ancestor_data(session)->imap_session;
207}
208
209static int imapdriver_cached_initialize(mailsession * session)
210{
211 struct imap_cached_session_state_data * data;
212
213 data = malloc(sizeof(* data));
214 if (data == NULL)
215 goto err;
216
217 data->imap_ancestor = mailsession_new(imap_session_driver);
218 if (data->imap_ancestor == NULL)
219 goto free_data;
220 data->imap_quoted_mb = NULL;
221 data->imap_cache_directory[0] = '\0';
222 data->imap_uid_list = carray_new(128);
223 if (data->imap_uid_list == NULL)
224 goto free_session;
225
226 session->sess_data = data;
227
228 return MAIL_NO_ERROR;
229
230 free_session:
231 mailsession_free(data->imap_ancestor);
232 free_data:
233 free(data);
234 err:
235 return MAIL_ERROR_MEMORY;
236}
237
238static void
239free_quoted_mb(struct imap_cached_session_state_data * imap_cached_data)
240{
241 if (imap_cached_data->imap_quoted_mb != NULL) {
242 free(imap_cached_data->imap_quoted_mb);
243 imap_cached_data->imap_quoted_mb = NULL;
244 }
245}
246
247struct uid_cache_item {
248 uint32_t uid;
249 uint32_t size;
250};
251
252static int update_uid_cache(mailsession * session,
253 struct mailmessage_list * env_list)
254{
255 unsigned int i;
256 int r;
257 struct imap_cached_session_state_data * data;
258 int res;
259
260 data = get_cached_data(session);
261
262 /* free all UID cache */
263 for(i = 0 ; i < carray_count(data->imap_uid_list) ; i ++) {
264 struct uid_cache_item * cache_item;
265
266 cache_item = carray_get(data->imap_uid_list, i);
267 free(cache_item);
268 }
269
270 /* build UID cache */
271 r = carray_set_size(data->imap_uid_list,
272 carray_count(env_list->msg_tab));
273 if (r < 0) {
274 res = MAIL_ERROR_MEMORY;
275 goto err;
276 }
277
278 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
279 struct uid_cache_item * cache_item;
280 mailmessage * msg;
281
282 cache_item = malloc(sizeof(* cache_item));
283 if (cache_item == NULL) {
284 res = MAIL_ERROR_MEMORY;
285 goto err;
286 }
287 msg = carray_get(env_list->msg_tab, i);
288 cache_item->uid = msg->msg_index;
289 cache_item->size = msg->msg_size;
290
291 carray_set(data->imap_uid_list, i, cache_item);
292 }
293
294 return MAIL_NO_ERROR;
295
296 err:
297 return res;
298}
299
300static void check_for_uid_cache(mailsession * session)
301{
302#if 0
303 mailsession * imap;
304#endif
305 mailimap * imap;
306#if 0
307 struct imap_session_state_data * imap_data;
308#endif
309 clist * list;
310 clistiter * cur;
311 struct imap_cached_session_state_data * data;
312 unsigned int i;
313 unsigned dest;
314
315 data = get_cached_data(session);
316#if 0
317 imap = get_ancestor(session);
318
319 imap_data = imap->data;
320#endif
321
322 imap = get_imap_session(session);
323
324 if (imap->imap_response_info == NULL)
325 return;
326
327 list = imap->imap_response_info->rsp_expunged;
328 if (list == NULL)
329 return;
330
331 dest = 0;
332 i = 0;
333 /* remove expunged */
334 for(cur = clist_begin(list) ; cur != NULL ; cur = clist_next(cur)) {
335 uint32_t expunged;
336
337 expunged = * (uint32_t *) clist_content(cur);
338
339 while (i < carray_count(data->imap_uid_list)) {
340 struct uid_cache_item * cache_item;
341
342 if (dest + 1 == expunged) {
343 cache_item = carray_get(data->imap_uid_list, i);
344 free(cache_item);
345 i ++;
346 break;
347 }
348 else {
349 cache_item = carray_get(data->imap_uid_list, i);
350 carray_set(data->imap_uid_list, dest, cache_item);
351 i ++;
352 dest ++;
353 }
354 }
355 }
356 /* complete list */
357 while (i < carray_count(data->imap_uid_list)) {
358 struct uid_cache_item * cache_item;
359
360 cache_item = carray_get(data->imap_uid_list, i);
361 carray_set(data->imap_uid_list, dest, cache_item);
362 i ++;
363 dest ++;
364 }
365 carray_set_size(data->imap_uid_list, dest);
366}
367
368static void imapdriver_cached_uninitialize(mailsession * session)
369{
370 struct imap_cached_session_state_data * data;
371 unsigned int i;
372
373 data = get_cached_data(session);
374
375 for(i = 0 ; i < carray_count(data->imap_uid_list) ; i ++) {
376 struct uid_cache_item * cache_item;
377
378 cache_item = carray_get(data->imap_uid_list, i);
379 free(cache_item);
380 }
381 carray_free(data->imap_uid_list);
382 free_quoted_mb(data);
383 mailsession_free(data->imap_ancestor);
384 free(data);
385
386 session->sess_data = NULL;
387}
388
389
390static int imapdriver_cached_parameters(mailsession * session,
391 int id, void * value)
392{
393 struct imap_cached_session_state_data * data;
394 int r;
395
396 data = get_cached_data(session);
397
398 switch (id) {
399 case IMAPDRIVER_CACHED_SET_CACHE_DIRECTORY:
400 strncpy(data->imap_cache_directory, value, PATH_MAX);
401 data->imap_cache_directory[PATH_MAX - 1] = '\0';
402
403 r = generic_cache_create_dir(data->imap_cache_directory);
404 if (r != MAIL_NO_ERROR)
405 return r;
406
407 return MAIL_NO_ERROR;
408 }
409
410 return MAIL_ERROR_INVAL;
411}
412
413
414static int imapdriver_cached_connect_stream(mailsession * session,
415 mailstream * s)
416{
417 int r;
418
419 check_for_uid_cache(session);
420
421 r = mailsession_connect_stream(get_ancestor(session), s);
422
423 check_for_uid_cache(session);
424
425 return r;
426}
427
428static int imapdriver_cached_starttls(mailsession * session)
429{
430 int r;
431
432 r = mailsession_starttls(get_ancestor(session));
433
434 check_for_uid_cache(session);
435
436 return r;
437}
438
439static int imapdriver_cached_login(mailsession * session,
440 char * userid, char * password)
441{
442 int r;
443
444 r = mailsession_login(get_ancestor(session), userid, password);
445
446 check_for_uid_cache(session);
447
448 return r;
449}
450
451static int imapdriver_cached_logout(mailsession * session)
452{
453 int r;
454
455 r = mailsession_logout(get_ancestor(session));
456
457 check_for_uid_cache(session);
458
459 if (r == MAIL_NO_ERROR) {
460 struct imap_cached_session_state_data * imap_cached_data;
461
462 imap_cached_data = get_cached_data(session);
463
464 free_quoted_mb(imap_cached_data);
465 }
466
467 return r;
468}
469
470static int imapdriver_cached_noop(mailsession * session)
471{
472 int r;
473
474 r = mailsession_noop(get_ancestor(session));
475
476 check_for_uid_cache(session);
477
478 return r;
479}
480
481static int imapdriver_cached_build_folder_name(mailsession * session,
482 char * mb,
483 char * name, char ** result)
484{
485 int r;
486
487 r = mailsession_build_folder_name(get_ancestor(session), mb,
488 name, result);
489
490 check_for_uid_cache(session);
491
492 return r;
493}
494
495static int imapdriver_cached_create_folder(mailsession * session, char * mb)
496{
497 int r;
498
499 r = mailsession_create_folder(get_ancestor(session), mb);
500
501 check_for_uid_cache(session);
502
503 return r;
504}
505
506static int imapdriver_cached_delete_folder(mailsession * session, char * mb)
507{
508 int r;
509
510 r = mailsession_delete_folder(get_ancestor(session), mb);
511
512 check_for_uid_cache(session);
513
514 return r;
515}
516
517static int imapdriver_cached_rename_folder(mailsession * session, char * mb,
518 char * new_name)
519{
520 int r;
521
522 r = mailsession_rename_folder(get_ancestor(session), mb, new_name);
523
524 check_for_uid_cache(session);
525
526 return r;
527}
528
529static int imapdriver_cached_check_folder(mailsession * session)
530{
531 int r;
532
533 r = mailsession_check_folder(get_ancestor(session));
534
535 check_for_uid_cache(session);
536
537 return r;
538}
539
540static int imapdriver_cached_examine_folder(mailsession * session,
541 char * mb)
542{
543 int r;
544
545 r = mailsession_examine_folder(get_ancestor(session), mb);
546
547 check_for_uid_cache(session);
548
549 return r;
550}
551
552static int get_cache_folder(mailsession * session, char ** result)
553{
554#if 0
555 mailsession * imap_session;
556#endif
557 mailimap * imap;
558 char * mb;
559 char * cache_dir;
560 char * dirname;
561 char * quoted_mb;
562 int res;
563 int r;
564 char key[PATH_MAX];
565#if 0
566 struct imap_session_state_data * imap_data;
567 struct imap_cached_session_state_data * cached_data;
568#endif
569
570#if 0
571 imap_session = get_ancestor(session);
572 imap_data = imap_session->data;
573 imap = imap_data->session;
574#endif
575 imap = get_imap_session(session);
576
577 mb = get_ancestor_data(session)->imap_mailbox;
578
579 cache_dir = get_cached_data(session)->imap_cache_directory;
580
581 if (imap->imap_state != MAILIMAP_STATE_SELECTED)
582 return MAIL_ERROR_BAD_STATE;
583
584 if (imap->imap_selection_info == NULL)
585 return MAIL_ERROR_BAD_STATE;
586
587 quoted_mb = maildriver_quote_mailbox(mb);
588 if (quoted_mb == NULL) {
589 res = MAIL_ERROR_MEMORY;
590 goto err;
591 }
592
593 snprintf(key, PATH_MAX, "%s/%s", cache_dir, quoted_mb);
594
595 dirname = strdup(key);
596 if (dirname == NULL) {
597 res = MAIL_ERROR_MEMORY;
598 goto free_mb;
599 }
600
601 r = generic_cache_create_dir(dirname);
602 if (r != MAIL_NO_ERROR) {
603 res = r;
604 goto free_dirname;
605 }
606
607 free(quoted_mb);
608
609 * result = dirname;
610
611 return MAIL_NO_ERROR;
612
613 free_dirname:
614 free(dirname);
615 free_mb:
616 free(quoted_mb);
617 err:
618 return res;
619}
620
621static int imapdriver_cached_select_folder(mailsession * session, char * mb)
622{
623 int r;
624 char * quoted_mb;
625 struct imap_cached_session_state_data * data;
626 mailsession * imap;
627 char * old_mb;
628
629 imap = get_ancestor(session);
630
631 old_mb = get_ancestor_data(session)->imap_mailbox;
632 if (old_mb != NULL)
633 if (strcmp(mb, old_mb) == 0)
634 return MAIL_NO_ERROR;
635
636 r = mailsession_select_folder(get_ancestor(session), mb);
637 if (r != MAIL_NO_ERROR)
638 return r;
639
640 check_for_uid_cache(session);
641
642 r = get_cache_folder(session, &quoted_mb);
643 if (r != MAIL_NO_ERROR)
644 return r;
645
646 data = get_cached_data(session);
647 if (data->imap_quoted_mb != NULL)
648 free(data->imap_quoted_mb);
649 data->imap_quoted_mb = quoted_mb;
650
651 /* clear UID cache */
652 carray_set_size(data->imap_uid_list, 0);
653
654 return MAIL_NO_ERROR;
655}
656
657static int imapdriver_cached_expunge_folder(mailsession * session)
658{
659 int r;
660
661 r = mailsession_expunge_folder(get_ancestor(session));
662
663 check_for_uid_cache(session);
664
665 return r;
666}
667
668static int imapdriver_cached_status_folder(mailsession * session, char * mb,
669 uint32_t * result_messages, uint32_t * result_recent,
670 uint32_t * result_unseen)
671{
672 int r;
673
674 r = mailsession_status_folder(get_ancestor(session), mb, result_messages,
675 result_recent, result_unseen);
676
677 check_for_uid_cache(session);
678
679 return r;
680}
681
682static int imapdriver_cached_messages_number(mailsession * session,
683 char * mb,
684 uint32_t * result)
685{
686 int r;
687
688 r = mailsession_messages_number(get_ancestor(session), mb, result);
689
690 check_for_uid_cache(session);
691
692 return r;
693}
694
695static int imapdriver_cached_recent_number(mailsession * session, char * mb,
696 uint32_t * result)
697{
698 int r;
699
700 r = mailsession_recent_number(get_ancestor(session), mb, result);
701
702 check_for_uid_cache(session);
703
704 return r;
705}
706
707static int imapdriver_cached_unseen_number(mailsession * session, char * mb,
708 uint32_t * result)
709{
710 int r;
711
712 r = mailsession_unseen_number(get_ancestor(session), mb, result);
713
714 check_for_uid_cache(session);
715
716 return r;
717}
718
719static int imapdriver_cached_list_folders(mailsession * session, char * mb,
720 struct mail_list ** result)
721{
722 int r;
723
724 r = mailsession_list_folders(get_ancestor(session), mb, result);
725
726 check_for_uid_cache(session);
727
728 return r;
729}
730
731static int imapdriver_cached_lsub_folders(mailsession * session, char * mb,
732 struct mail_list ** result)
733{
734 int r;
735
736 r = mailsession_lsub_folders(get_ancestor(session), mb, result);
737
738 check_for_uid_cache(session);
739
740 return r;
741}
742
743static int imapdriver_cached_subscribe_folder(mailsession * session,
744 char * mb)
745{
746 int r;
747
748 r = mailsession_subscribe_folder(get_ancestor(session), mb);
749
750 check_for_uid_cache(session);
751
752 return r;
753}
754
755static int imapdriver_cached_unsubscribe_folder(mailsession * session,
756 char * mb)
757{
758 int r;
759
760 r = mailsession_unsubscribe_folder(get_ancestor(session), mb);
761
762 check_for_uid_cache(session);
763
764 return r;
765}
766
767static int imapdriver_cached_append_message(mailsession * session,
768 char * message, size_t size)
769{
770 int r;
771
772 r = mailsession_append_message(get_ancestor(session), message, size);
773
774 check_for_uid_cache(session);
775
776 return r;
777}
778
779static int imapdriver_cached_copy_message(mailsession * session,
780 uint32_t num, char * mb)
781{
782 int r;
783
784 r = mailsession_copy_message(get_ancestor(session), num, mb);
785
786 check_for_uid_cache(session);
787
788 return r;
789}
790
791static int cmp_uid(uint32_t ** pa, uint32_t ** pb)
792{
793 uint32_t * a;
794 uint32_t * b;
795
796 a = * pa;
797 b = * pb;
798
799 return * a - * b;
800}
801
802
803static int imapdriver_cached_get_messages_list(mailsession * session,
804 struct mailmessage_list **
805 result)
806{
807#if 0
808 mailsession * imap_session;
809#endif
810 mailimap * imap;
811 uint32_t uid_max;
812 struct imap_cached_session_state_data * data;
813 struct mailmessage_list * env_list;
814 unsigned i;
815 int r;
816 int res;
817 carray * tab;
818
819#if 0
820 data = session->data;
821 imap_session = get_ancestor(session);
822 imap = ((struct imap_session_state_data *) (imap_session->data))->session;
823#endif
824 data = get_cached_data(session);
825 imap = get_imap_session(session);
826
827 uid_max = 0;
828
829#ifdef CACHE_MESSAGE_LIST
830 /* get UID max */
831 uid_max = 0;
832 for(i = 0 ; i < carray_count(data->imap_uid_list) ; i ++) {
833 struct uid_cache_item * cache_item;
834
835 cache_item = carray_get(data->imap_uid_list, i);
836 if (cache_item->uid > uid_max)
837 uid_max = cache_item->uid;
838 }
839#endif
840
841 r = imap_get_messages_list(imap, session, imap_cached_message_driver,
842 uid_max + 1, &env_list);
843
844 check_for_uid_cache(session);
845
846 if (r != MAIL_NO_ERROR) {
847 res = r;
848 goto err;
849 }
850
851#ifdef CACHE_MESSAGE_LIST
852 /* remove unsollicited message */
853 i = 0;
854 while (i < carray_count(env_list->msg_tab)) {
855 mailmessage * msg;
856
857 msg = carray_get(env_list->msg_tab, i);
858 if (msg->msg_index < uid_max + 1)
859 carray_delete(env_list->msg_tab, i);
860 else
861 i ++;
862 }
863
864 tab = carray_new(carray_count(env_list->msg_tab) +
865 carray_count(data->imap_uid_list));
866 if (tab == NULL) {
867 res = MAIL_ERROR_MEMORY;
868 goto free;
869 }
870 carray_set_size(tab,
871 carray_count(env_list->msg_tab) + carray_count(data->imap_uid_list));
872
873 /* sort cached data before adding them to the list */
874 qsort(carray_data(data->imap_uid_list), carray_count(data->imap_uid_list),
875 sizeof(* carray_data(data->imap_uid_list)),
876 (int (*)(const void *, const void *)) cmp_uid);
877
878 /* adds cached UID */
879 for(i = 0 ; i < carray_count(data->imap_uid_list) ; i ++) {
880 struct uid_cache_item * cache_item;
881 mailmessage * msg;
882
883 cache_item = carray_get(data->imap_uid_list, i);
884
885 msg = mailmessage_new();
886 if (msg == NULL) {
887 res = MAIL_ERROR_MEMORY;
888 goto free;
889 }
890
891 r = mailmessage_init(msg, session, imap_cached_message_driver,
892 cache_item->uid, cache_item->size);
893 if (r != MAIL_NO_ERROR) {
894 mailmessage_free(msg);
895 res = r;
896 goto free;
897 }
898
899 carray_set(tab, i, msg);
900 }
901
902 /* adds new elements */
903 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
904 mailmessage * msg;
905
906 msg = carray_get(env_list->msg_tab, i);
907 carray_set(tab, carray_count(data->imap_uid_list) + i, msg);
908 }
909
910 /* replace list of messages in env_list */
911 carray_free(env_list->msg_tab);
912 env_list->msg_tab = tab;
913
914 r = update_uid_cache(session, env_list);
915 if (r != MAIL_NO_ERROR) {
916 res = r;
917 goto free;
918 }
919#endif
920
921 * result = env_list;
922
923 return MAIL_NO_ERROR;
924
925 free:
926 mailmessage_list_free(env_list);
927 err:
928 return res;
929}
930
931static int get_flags_list(mailsession * session,
932 struct mailmessage_list * env_list)
933{
934 struct mailimap_set * set;
935 struct mailimap_fetch_att * fetch_att;
936 struct mailimap_fetch_type * fetch_type;
937 int res;
938 clist * fetch_result;
939 int r;
940 clist * msg_list;
941#if 0
942 struct imap_session_state_data * data;
943#endif
944 unsigned i;
945 unsigned dest;
946
947#if 0
948 data = session->data;
949#endif
950
951 fetch_type = mailimap_fetch_type_new_fetch_att_list_empty();
952 if (fetch_type == NULL) {
953 res = MAIL_ERROR_MEMORY;
954 goto err;
955 }
956
957 fetch_att = mailimap_fetch_att_new_uid();
958 if (fetch_att == NULL) {
959 res = MAIL_ERROR_MEMORY;
960 goto free_fetch_type;
961 }
962
963 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
964 if (r != MAILIMAP_NO_ERROR) {
965 mailimap_fetch_att_free(fetch_att);
966 res = MAIL_ERROR_MEMORY;
967 goto free_fetch_type;
968 }
969
970 fetch_att = mailimap_fetch_att_new_flags();
971 if (fetch_att == NULL) {
972 res = MAIL_ERROR_MEMORY;
973 goto free_fetch_type;
974 }
975
976 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
977 if (r != MAILIMAP_NO_ERROR) {
978 mailimap_fetch_att_free(fetch_att);
979 res = MAIL_ERROR_MEMORY;
980 goto free_fetch_type;
981 }
982
983 r = maildriver_env_list_to_msg_list_no_flags(env_list, &msg_list);
984 if (r != MAIL_NO_ERROR) {
985 res = MAIL_ERROR_MEMORY;
986 goto free_fetch_type;
987 }
988
989 if (clist_begin(msg_list) == NULL) {
990 /* no need to fetch envelopes */
991
992 clist_free(msg_list);
993 mailimap_fetch_type_free(fetch_type);
994 return MAIL_NO_ERROR;
995 }
996
997 r = msg_list_to_imap_set(msg_list, &set);
998 if (r != MAIL_NO_ERROR) {
999 clist_foreach(msg_list, (clist_func) free, NULL);
1000 clist_free(msg_list);
1001 res = MAIL_ERROR_MEMORY;
1002 goto free_fetch_type;
1003 }
1004 clist_foreach(msg_list, (clist_func) free, NULL);
1005 clist_free(msg_list);
1006
1007 r = mailimap_uid_fetch(get_imap_session(session), set,
1008 fetch_type, &fetch_result);
1009
1010 mailimap_fetch_type_free(fetch_type);
1011 mailimap_set_free(set);
1012
1013 switch (r) {
1014 case MAILIMAP_NO_ERROR:
1015 break;
1016 default:
1017 return imap_error_to_mail_error(r);
1018 }
1019
1020 r = imap_fetch_result_to_envelop_list(fetch_result, env_list);
1021 mailimap_fetch_list_free(fetch_result);
1022
1023 if (r != MAIL_NO_ERROR) {
1024 res = MAIL_ERROR_MEMORY;
1025 goto err;
1026 }
1027
1028 /* remove messages that don't have flags */
1029 i = 0;
1030 dest = 0;
1031 while (i < carray_count(env_list->msg_tab)) {
1032 mailmessage * msg;
1033
1034 msg = carray_get(env_list->msg_tab, i);
1035 if (msg->msg_flags != NULL) {
1036 carray_set(env_list->msg_tab, dest, msg);
1037 dest ++;
1038 }
1039 else {
1040 mailmessage_free(msg);
1041 }
1042 i ++;
1043 }
1044 carray_set_size(env_list->msg_tab, dest);
1045
1046 return MAIL_NO_ERROR;
1047
1048 free_fetch_type:
1049 mailimap_fetch_type_free(fetch_type);
1050 err:
1051 return res;
1052}
1053
1054
1055#define ENV_NAME "env.db"
1056
1057static void get_uid_from_filename(char * filename)
1058{
1059 char * p;
1060
1061 p = strstr(filename, "-part");
1062 if (p != NULL)
1063 * p = 0;
1064 p = strstr(filename, "-envelope");
1065 if (p != NULL)
1066 * p = 0;
1067 p = strstr(filename, "-rfc822");
1068 if (p != NULL)
1069 * p = 0;
1070}
1071
1072static int
1073imapdriver_cached_get_envelopes_list(mailsession * session,
1074 struct mailmessage_list * env_list)
1075{
1076 int r;
1077 int res;
1078 uint32_t i;
1079 struct imap_cached_session_state_data * data;
1080 MMAPString * mmapstr;
1081 struct mail_cache_db * cache_db;
1082 char filename[PATH_MAX];
1083
1084 data = get_cached_data(session);
1085 if (data->imap_quoted_mb == NULL) {
1086 res = MAIL_ERROR_BAD_STATE;
1087 goto err;
1088 }
1089
1090 mmapstr = mmap_string_new("");
1091 if (mmapstr == NULL) {
1092 res = MAIL_ERROR_MEMORY;
1093 goto err;
1094 }
1095
1096 snprintf(filename, PATH_MAX, "%s/%s", data->imap_quoted_mb, ENV_NAME);
1097
1098 r = mail_cache_db_open_lock(filename, &cache_db);
1099 if (r < 0) {
1100 res = MAIL_ERROR_MEMORY;
1101 goto free_mmapstr;
1102 }
1103
1104 /* fill with cached */
1105
1106 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1107 mailmessage * msg;
1108 struct mailimf_fields * fields;
1109
1110 msg = carray_get(env_list->msg_tab, i);
1111
1112 if (msg->msg_fields == NULL) {
1113 r = imapdriver_get_cached_envelope(cache_db, mmapstr,
1114 session, msg, &fields);
1115 if (r == MAIL_NO_ERROR) {
1116 msg->msg_cached = TRUE;
1117 msg->msg_fields = fields;
1118 }
1119 }
1120 }
1121
1122 mail_cache_db_close_unlock(filename, cache_db);
1123
1124 r = mailsession_get_envelopes_list(get_ancestor(session), env_list);
1125
1126 check_for_uid_cache(session);
1127
1128 if (r != MAIL_NO_ERROR) {
1129 res = r;
1130 goto free_mmapstr;
1131 }
1132
1133 r = get_flags_list(session, env_list);
1134
1135 if (r != MAIL_NO_ERROR) {
1136 res = r;
1137 goto free_mmapstr;
1138 }
1139
1140#ifdef CACHE_MESSAGE_LIST
1141 r = update_uid_cache(session, env_list);
1142 if (r != MAIL_NO_ERROR) {
1143 res = r;
1144 goto free_mmapstr;
1145 }
1146#endif
1147
1148 /* must write cache */
1149
1150 r = mail_cache_db_open_lock(filename, &cache_db);
1151 if (r < 0) {
1152 res = MAIL_ERROR_MEMORY;
1153 goto free_mmapstr;
1154 }
1155
1156 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1157 mailmessage * msg;
1158
1159 msg = carray_get(env_list->msg_tab, i);
1160
1161 if (msg->msg_fields != NULL) {
1162 if (!msg->msg_cached) {
1163 r = imapdriver_write_cached_envelope(cache_db, mmapstr,
1164 session, msg, msg->msg_fields);
1165 }
1166 }
1167 }
1168
1169 /* flush cache */
1170
1171 maildriver_cache_clean_up(cache_db, NULL, env_list);
1172
1173 mail_cache_db_close_unlock(filename, cache_db);
1174 mmap_string_free(mmapstr);
1175
1176 /* remove cache files */
1177
1178 maildriver_message_cache_clean_up(data->imap_quoted_mb, env_list,
1179 get_uid_from_filename);
1180
1181 return MAIL_NO_ERROR;
1182
1183 free_mmapstr:
1184 mmap_string_free(mmapstr);
1185 err:
1186 return res;
1187}
1188
1189static int imapdriver_cached_remove_message(mailsession * session,
1190 uint32_t num)
1191{
1192 int r;
1193
1194 r = mailsession_remove_message(get_ancestor(session), num);
1195
1196 check_for_uid_cache(session);
1197
1198 return r;
1199}
1200
1201#if 0
1202static int imapdriver_cached_search_messages(mailsession * session,
1203 char * charset,
1204 struct mail_search_key * key,
1205 struct mail_search_result **
1206 result)
1207{
1208 int r;
1209
1210 r = mailsession_search_messages(get_ancestor(session), charset, key, result);
1211
1212 check_for_uid_cache(session);
1213
1214 return r;
1215}
1216#endif
1217
1218static int imapdriver_cached_get_message(mailsession * session,
1219 uint32_t num, mailmessage ** result)
1220{
1221 mailmessage * msg_info;
1222 int r;
1223
1224 msg_info = mailmessage_new();
1225 if (msg_info == NULL)
1226 return MAIL_ERROR_MEMORY;
1227
1228 r = mailmessage_init(msg_info, session, imap_cached_message_driver, num, 0);
1229 if (r != MAIL_NO_ERROR) {
1230 mailmessage_free(msg_info);
1231 return r;
1232 }
1233
1234 * result = msg_info;
1235
1236 return MAIL_NO_ERROR;
1237}
1238
1239/* Retrieve a message by UID
1240 * libEtPan! uid format for IMAP is "UIDVALIDITY-UID"
1241 * where UIDVALIDITY and UID are decimal representation of
1242 * respectively uidvalidity and uid numbers.
1243 * Return value:
1244 * MAIL_ERROR_INVAL if uid is NULL or has an incorrect format.
1245 * MAIL_ERROR_MSG_NOT_FOUND if uidvalidity has changed or uid was not found
1246 * MAIL_NO_ERROR if message was found. Result is in result
1247 */
1248static int imapdriver_cached_get_message_by_uid(mailsession * session,
1249 const char * uid,
1250 mailmessage ** result)
1251{
1252 uint32_t uidvalidity;
1253 uint32_t num;
1254 char * p1, * p2;
1255 mailimap *imap;
1256
1257 if (uid == NULL)
1258 return MAIL_ERROR_INVAL;
1259
1260 uidvalidity = strtoul(uid, &p1, 10);
1261 if (p1 == uid || * p1 != '-')
1262 return MAIL_ERROR_INVAL;
1263
1264 p1++;
1265 num = strtoul(p1, &p2, 10);
1266 if (p2 == p1 || * p2 != '\0')
1267 return MAIL_ERROR_INVAL;
1268
1269 imap = get_imap_session(session);
1270 if (imap->imap_selection_info->sel_uidvalidity != uidvalidity)
1271 return MAIL_ERROR_MSG_NOT_FOUND;
1272
1273 return imapdriver_cached_get_message(session, num, result);
1274}
diff --git a/kmicromail/libetpan/generic/imapdriver_cached.h b/kmicromail/libetpan/generic/imapdriver_cached.h
new file mode 100644
index 0000000..92bb60d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_cached.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef IMAPDRIVER_CACHED_H
37
38#define IMAPDRIVER_CACHED_H
39
40#include <libetpan/imapdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * imap_cached_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/imapdriver_cached_message.c b/kmicromail/libetpan/generic/imapdriver_cached_message.c
new file mode 100644
index 0000000..c0542a3
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_cached_message.c
@@ -0,0 +1,664 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "imapdriver_cached_message.h"
37
38#include "imapdriver_tools.h"
39#include "imapdriver_message.h"
40#include "imapdriver_cached.h"
41#include "imapdriver_types.h"
42#include "imapdriver.h"
43#include "mailmessage.h"
44#include "generic_cache.h"
45#include "mail_cache_db.h"
46
47#include <string.h>
48#include <stdlib.h>
49
50static int imap_initialize(mailmessage * msg_info);
51
52static void imap_uninitialize(mailmessage * msg_info);
53
54static void imap_flush(mailmessage * msg_info);
55
56static void imap_check(mailmessage * msg_info);
57
58static void imap_fetch_result_free(mailmessage * msg_info,
59 char * msg);
60
61static int imap_fetch(mailmessage * msg_info,
62 char ** result,
63 size_t * result_len);
64
65static int imap_fetch_header(mailmessage * msg_info,
66 char ** result,
67 size_t * result_len);
68
69static int imap_fetch_body(mailmessage * msg_info,
70 char ** result, size_t * result_len);
71
72static int imap_fetch_size(mailmessage * msg_info,
73 size_t * result);
74
75static int imap_get_bodystructure(mailmessage * msg_info,
76 struct mailmime ** result);
77
78static int imap_fetch_section(mailmessage * msg_info,
79 struct mailmime * mime,
80 char ** result, size_t * result_len);
81
82static int imap_fetch_section_header(mailmessage * msg_info,
83 struct mailmime * mime,
84 char ** result,
85 size_t * result_len);
86
87static int imap_fetch_section_mime(mailmessage * msg_info,
88 struct mailmime * mime,
89 char ** result,
90 size_t * result_len);
91
92static int imap_fetch_section_body(mailmessage * msg_info,
93 struct mailmime * mime,
94 char ** result,
95 size_t * result_len);
96
97
98static int imap_fetch_envelope(mailmessage * msg_info,
99 struct mailimf_fields ** result);
100
101static int imap_get_flags(mailmessage * msg_info,
102 struct mail_flags ** result);
103
104static mailmessage_driver local_imap_cached_message_driver = {
105 .msg_name = "imap-cached",
106
107 .msg_initialize = imap_initialize,
108 .msg_uninitialize = imap_uninitialize,
109
110 .msg_flush = imap_flush,
111 .msg_check = imap_check,
112
113 .msg_fetch_result_free = imap_fetch_result_free,
114
115 .msg_fetch = imap_fetch,
116 .msg_fetch_header = imap_fetch_header,
117 .msg_fetch_body = imap_fetch_body,
118 .msg_fetch_size = imap_fetch_size,
119 .msg_get_bodystructure = imap_get_bodystructure,
120 .msg_fetch_section = imap_fetch_section,
121 .msg_fetch_section_header = imap_fetch_section_header,
122 .msg_fetch_section_mime = imap_fetch_section_mime,
123 .msg_fetch_section_body = imap_fetch_section_body,
124 .msg_fetch_envelope = imap_fetch_envelope,
125
126 .msg_get_flags = imap_get_flags,
127};
128
129mailmessage_driver * imap_cached_message_driver =
130&local_imap_cached_message_driver;
131
132static inline struct imap_cached_session_state_data *
133get_cached_session_data(mailmessage * msg)
134{
135 return msg->msg_session->sess_data;
136}
137
138static inline mailmessage * get_ancestor(mailmessage * msg_info)
139{
140 return msg_info->msg_data;
141}
142
143static inline struct imap_cached_session_state_data *
144cached_session_get_data(mailsession * s)
145{
146 return s->sess_data;
147}
148
149static inline mailsession * cached_session_get_ancestor(mailsession * s)
150{
151 return cached_session_get_data(s)->imap_ancestor;
152}
153
154static inline struct imap_session_state_data *
155cached_session_get_ancestor_data(mailsession * s)
156{
157 return cached_session_get_ancestor(s)->sess_data;
158}
159
160static inline mailimap *
161cached_session_get_imap_session(mailsession * session)
162{
163 return cached_session_get_ancestor_data(session)->imap_session;
164}
165
166static inline mailimap * get_imap_session(mailmessage * msg)
167{
168 return cached_session_get_imap_session(msg->msg_session);
169}
170
171static inline mailsession * get_ancestor_session(mailmessage * msg_info)
172{
173 return cached_session_get_ancestor(msg_info->msg_session);
174}
175
176
177static void generate_key_from_mime_section(char * key, size_t size,
178 struct mailmime * mime)
179{
180 clistiter * cur;
181 MMAPString * gstr;
182 struct mailmime_section * part;
183 int r;
184
185 snprintf(key, size, "unvalid");
186
187 r = mailmime_get_section_id(mime, &part);
188 if (r != MAILIMF_NO_ERROR)
189 goto err;
190
191 gstr = mmap_string_new("part");
192 if (gstr == NULL)
193 goto free_section;
194
195 for(cur = clist_begin(part->sec_list) ;
196 cur != NULL ; cur = clist_next(cur)) {
197 char s[20];
198
199 snprintf(s, 20, ".%u", * (uint32_t *) clist_content(cur));
200 if (mmap_string_append(gstr, s) == NULL)
201 goto free_str;
202 }
203
204 snprintf(key, size, "%s", gstr->str);
205
206 mmap_string_free(gstr);
207 mailmime_section_free(part);
208
209 return;
210
211 free_str:
212 mmap_string_free(gstr);
213 free_section:
214 mailmime_section_free(part);
215 err:
216}
217
218static void generate_key_from_section(char * key, size_t size,
219 mailmessage * msg_info,
220 struct mailmime * mime, int type)
221{
222 char section_str[PATH_MAX];
223
224 generate_key_from_mime_section(section_str, PATH_MAX, mime);
225
226 switch (type) {
227 case IMAP_SECTION_MESSAGE:
228 snprintf(key, size, "%s-%s", msg_info->msg_uid, section_str);
229 break;
230 case IMAP_SECTION_HEADER:
231 snprintf(key, size, "%s-%s-header", msg_info->msg_uid, section_str);
232 break;
233 case IMAP_SECTION_MIME:
234 snprintf(key, size, "%s-%s-mime", msg_info->msg_uid, section_str);
235 break;
236 case IMAP_SECTION_BODY:
237 snprintf(key, size, "%s-%s-text", msg_info->msg_uid, section_str);
238 break;
239 }
240}
241
242static void generate_key_from_message(char * key, size_t size,
243 mailmessage * msg_info,
244 int type)
245{
246 switch (type) {
247 case MAILIMAP_MSG_ATT_RFC822:
248 snprintf(key, size, "%s-rfc822", msg_info->msg_uid);
249 break;
250 case MAILIMAP_MSG_ATT_RFC822_HEADER:
251 snprintf(key, size, "%s-rfc822-header", msg_info->msg_uid);
252 break;
253 case MAILIMAP_MSG_ATT_RFC822_TEXT:
254 snprintf(key, size, "%s-rfc822-text", msg_info->msg_uid);
255 break;
256 case MAILIMAP_MSG_ATT_ENVELOPE:
257 snprintf(key, size, "%s-envelope", msg_info->msg_uid);
258 break;
259 }
260}
261
262static void build_cache_name(char * filename, size_t size,
263 mailmessage * msg, char * key)
264{
265 char * quoted_mb;
266
267 quoted_mb = get_cached_session_data(msg)->imap_quoted_mb;
268
269 snprintf(filename, size, "%s/%s", quoted_mb, key);
270}
271
272static int imap_initialize(mailmessage * msg_info)
273{
274 mailmessage * ancestor;
275 int r;
276 char key[PATH_MAX];
277 char * uid;
278 mailimap * imap;
279
280 ancestor = mailmessage_new();
281 if (ancestor == NULL)
282 return MAIL_ERROR_MEMORY;
283
284 r = mailmessage_init(ancestor, get_ancestor_session(msg_info),
285 imap_message_driver,
286 msg_info->msg_index, 0);
287 if (r != MAIL_NO_ERROR) {
288 mailmessage_free(ancestor);
289 return r;
290 }
291
292 imap = get_imap_session(msg_info);
293
294 snprintf(key, PATH_MAX, "%u-%u",
295 imap->imap_selection_info->sel_uidvalidity, msg_info->msg_index);
296 uid = strdup(key);
297 if (uid == NULL) {
298 mailmessage_free(ancestor);
299 return MAIL_ERROR_MEMORY;
300 }
301
302 msg_info->msg_data = ancestor;
303 msg_info->msg_uid = uid;
304
305 return MAIL_NO_ERROR;
306}
307
308static void imap_uninitialize(mailmessage * msg_info)
309{
310 mailmessage_free(get_ancestor(msg_info));
311 msg_info->msg_data = NULL;
312}
313
314static void imap_flush(mailmessage * msg_info)
315{
316 if (msg_info->msg_mime != NULL) {
317 mailmime_free(msg_info->msg_mime);
318 msg_info->msg_mime = NULL;
319 }
320}
321
322static void imap_check(mailmessage * msg_info)
323{
324 get_ancestor(msg_info)->msg_flags = msg_info->msg_flags;
325 mailmessage_check(get_ancestor(msg_info));
326 get_ancestor(msg_info)->msg_flags = NULL;
327}
328
329static void imap_fetch_result_free(mailmessage * msg_info,
330 char * msg)
331{
332 mailmessage_fetch_result_free(get_ancestor(msg_info), msg);
333}
334
335static int imap_fetch(mailmessage * msg_info,
336 char ** result,
337 size_t * result_len)
338{
339 char key[PATH_MAX];
340 char filename[PATH_MAX];
341 int r;
342 char * str;
343 size_t len;
344
345 generate_key_from_message(key, PATH_MAX,
346 msg_info, MAILIMAP_MSG_ATT_RFC822);
347
348 build_cache_name(filename, PATH_MAX, msg_info, key);
349
350 r = generic_cache_read(filename, &str, &len);
351 if (r == MAIL_NO_ERROR) {
352 * result = str;
353 * result_len = len;
354
355 return MAIL_NO_ERROR;
356 }
357
358 r = mailmessage_fetch(get_ancestor(msg_info),
359 result, result_len);
360 if (r == MAIL_NO_ERROR)
361 generic_cache_store(filename, * result, strlen(* result));
362
363 return r;
364}
365
366static int imap_fetch_header(mailmessage * msg_info,
367 char ** result,
368 size_t * result_len)
369{
370 char key[PATH_MAX];
371 char filename[PATH_MAX];
372 int r;
373 char * str;
374 size_t len;
375
376 generate_key_from_message(key, PATH_MAX,
377 msg_info, MAILIMAP_MSG_ATT_RFC822_HEADER);
378
379 build_cache_name(filename, PATH_MAX, msg_info, key);
380
381 r = generic_cache_read(filename, &str, &len);
382 if (r == MAIL_NO_ERROR) {
383 * result = str;
384 * result_len = len;
385
386 return MAIL_NO_ERROR;
387 }
388
389 r = mailmessage_fetch_header(get_ancestor(msg_info), result,
390 result_len);
391 if (r == MAIL_NO_ERROR)
392 generic_cache_store(filename, * result, * result_len);
393
394 return r;
395}
396
397static int imap_fetch_body(mailmessage * msg_info,
398 char ** result, size_t * result_len)
399{
400 char key[PATH_MAX];
401 char filename[PATH_MAX];
402 int r;
403 char * str;
404 size_t len;
405
406 generate_key_from_message(key, PATH_MAX,
407 msg_info, MAILIMAP_MSG_ATT_RFC822_TEXT);
408
409 build_cache_name(filename, PATH_MAX, msg_info, key);
410
411 r = generic_cache_read(filename, &str, &len);
412 if (r == MAIL_NO_ERROR) {
413 * result = str;
414 * result_len = len;
415 return MAIL_NO_ERROR;
416 }
417
418 r = mailmessage_fetch_body(get_ancestor(msg_info), result,
419 result_len);
420 if (r == MAIL_NO_ERROR)
421 generic_cache_store(filename, * result, * result_len);
422
423 return r;
424}
425
426static int imap_fetch_size(mailmessage * msg_info,
427 size_t * result)
428{
429 return mailmessage_fetch_size(get_ancestor(msg_info), result);
430}
431
432static int imap_get_bodystructure(mailmessage * msg_info,
433 struct mailmime ** result)
434{
435 int r;
436
437 if (msg_info->msg_mime != NULL) {
438 * result = msg_info->msg_mime;
439
440 return MAIL_NO_ERROR;
441 }
442
443 r = mailmessage_get_bodystructure(get_ancestor(msg_info),
444 result);
445 if (r == MAIL_NO_ERROR) {
446 msg_info->msg_mime = get_ancestor(msg_info)->msg_mime;
447 get_ancestor(msg_info)->msg_mime = NULL;
448 }
449
450 return r;
451}
452
453static int imap_fetch_section(mailmessage * msg_info,
454 struct mailmime * mime,
455 char ** result, size_t * result_len)
456{
457 char key[PATH_MAX];
458 char filename[PATH_MAX];
459 int r;
460 char * str;
461 size_t len;
462
463 generate_key_from_section(key, PATH_MAX,
464 msg_info, mime, IMAP_SECTION_MESSAGE);
465
466 build_cache_name(filename, PATH_MAX, msg_info, key);
467
468 r = generic_cache_read(filename, &str, &len);
469 if (r == MAIL_NO_ERROR) {
470 * result = str;
471 * result_len = len;
472
473 return MAIL_NO_ERROR;
474 }
475
476 r = mailmessage_fetch_section(get_ancestor(msg_info),
477 mime, result, result_len);
478 if (r == MAIL_NO_ERROR)
479 generic_cache_store(filename, * result, * result_len);
480
481 return r;
482}
483
484static int imap_fetch_section_header(mailmessage * msg_info,
485 struct mailmime * mime,
486 char ** result,
487 size_t * result_len)
488{
489 char key[PATH_MAX];
490 char filename[PATH_MAX];
491 int r;
492 char * str;
493 size_t len;
494
495 generate_key_from_section(key, PATH_MAX,
496 msg_info, mime, IMAP_SECTION_HEADER);
497
498 build_cache_name(filename, PATH_MAX, msg_info, key);
499
500 r = generic_cache_read(filename, &str, &len);
501 if (r == MAIL_NO_ERROR) {
502 * result = str;
503 * result_len = len;
504
505 return MAIL_NO_ERROR;
506 }
507
508 r = mailmessage_fetch_section_header(get_ancestor(msg_info),
509 mime, result, result_len);
510 if (r == MAIL_NO_ERROR)
511 generic_cache_store(filename, * result, * result_len);
512
513 return r;
514}
515
516static int imap_fetch_section_mime(mailmessage * msg_info,
517 struct mailmime * mime,
518 char ** result,
519 size_t * result_len)
520{
521 char key[PATH_MAX];
522 char filename[PATH_MAX];
523 int r;
524 char * str;
525 size_t len;
526
527 generate_key_from_section(key, PATH_MAX,
528 msg_info, mime, IMAP_SECTION_MIME);
529
530 build_cache_name(filename, PATH_MAX, msg_info, key);
531
532 r = generic_cache_read(filename, &str, &len);
533 if (r == MAIL_NO_ERROR) {
534 * result = str;
535 * result_len = len;
536
537 return MAIL_NO_ERROR;
538 }
539
540 r = mailmessage_fetch_section_mime(get_ancestor(msg_info),
541 mime, result, result_len);
542 if (r == MAIL_NO_ERROR)
543 generic_cache_store(filename, * result, * result_len);
544
545 return r;
546}
547
548static int imap_fetch_section_body(mailmessage * msg_info,
549 struct mailmime * mime,
550 char ** result,
551 size_t * result_len)
552{
553 char key[PATH_MAX];
554 char filename[PATH_MAX];
555 int r;
556 char * str;
557 size_t len;
558
559 generate_key_from_section(key, PATH_MAX,
560 msg_info, mime, IMAP_SECTION_BODY);
561
562 build_cache_name(filename, PATH_MAX, msg_info, key);
563
564 r = generic_cache_read(filename, &str, &len);
565 if (r == MAIL_NO_ERROR) {
566
567 * result = str;
568 * result_len = len;
569
570 return MAIL_NO_ERROR;
571 }
572
573 r = mailmessage_fetch_section_body(get_ancestor(msg_info),
574 mime, result, result_len);
575 if (r == MAIL_NO_ERROR)
576 generic_cache_store(filename, * result, * result_len);
577
578 return r;
579}
580
581static int imap_get_flags(mailmessage * msg_info,
582 struct mail_flags ** result)
583{
584 int r;
585 struct mail_flags * flags;
586
587 if (msg_info->msg_flags != NULL) {
588 * result = msg_info->msg_flags;
589 return MAIL_NO_ERROR;
590 }
591
592 r = mailmessage_get_flags(get_ancestor(msg_info), &flags);
593 if (r != MAIL_NO_ERROR)
594 return r;
595
596 get_ancestor(msg_info)->msg_flags = NULL;
597 msg_info->msg_flags = flags;
598 * result = flags;
599
600 return MAIL_NO_ERROR;
601}
602
603#define ENV_NAME "env.db"
604
605static int imap_fetch_envelope(mailmessage * msg_info,
606 struct mailimf_fields ** result)
607{
608 struct mailimf_fields * fields;
609 int r;
610 struct mail_cache_db * cache_db;
611 MMAPString * mmapstr;
612 char filename[PATH_MAX];
613 struct imap_cached_session_state_data * data;
614 int res;
615
616 data = get_cached_session_data(msg_info);
617 if (data->imap_quoted_mb == NULL) {
618 res = MAIL_ERROR_BAD_STATE;
619 goto err;
620 }
621
622 snprintf(filename, PATH_MAX, "%s/%s", data->imap_quoted_mb, ENV_NAME);
623
624 r = mail_cache_db_open_lock(filename, &cache_db);
625 if (r < 0) {
626 res = MAIL_ERROR_MEMORY;
627 goto err;
628 }
629
630 mmapstr = mmap_string_new("");
631 if (mmapstr == NULL) {
632 res = MAIL_ERROR_MEMORY;
633 goto close_db;
634 }
635
636 r = imapdriver_get_cached_envelope(cache_db, mmapstr,
637 msg_info->msg_session, msg_info, &fields);
638
639 if ((r != MAIL_ERROR_CACHE_MISS) && (r != MAIL_NO_ERROR)) {
640 res = r;
641 goto close_db;
642 }
643
644 r = mailmessage_fetch_envelope(get_ancestor(msg_info), &fields);
645 if (r != MAIL_NO_ERROR) {
646 res = r;
647 goto close_db;
648 }
649
650 r = imapdriver_write_cached_envelope(cache_db, mmapstr,
651 msg_info->msg_session, msg_info, fields);
652
653 * result = fields;
654
655 mmap_string_free(mmapstr);
656 mail_cache_db_close_unlock(filename, cache_db);
657
658 return MAIL_NO_ERROR;
659
660 close_db:
661 mail_cache_db_close_unlock(filename, cache_db);
662 err:
663 return res;
664}
diff --git a/kmicromail/libetpan/generic/imapdriver_cached_message.h b/kmicromail/libetpan/generic/imapdriver_cached_message.h
new file mode 100644
index 0000000..49d63cb
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_cached_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef IMAPDRIVER_CACHED_MESSAGE_H
37
38#define IMAPDRIVER_CACHED_MESSAGE_H
39
40#include <libetpan/imapdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * imap_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/imapdriver_message.c b/kmicromail/libetpan/generic/imapdriver_message.c
new file mode 100644
index 0000000..47c7f78
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_message.c
@@ -0,0 +1,1239 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "imapdriver_message.h"
37
38#include "imapdriver_tools.h"
39#include "imapdriver.h"
40#include "imapdriver_types.h"
41#include "mailimap.h"
42#include "maildriver_tools.h"
43#include "generic_cache.h"
44
45#include <stdlib.h>
46#include <string.h>
47
48static int imap_initialize(mailmessage * msg_info);
49
50static void imap_fetch_result_free(mailmessage * msg_info,
51 char * msg);
52
53static int imap_fetch(mailmessage * msg_info,
54 char ** result,
55 size_t * result_len);
56
57static int imap_fetch_header(mailmessage * msg_info,
58 char ** result,
59 size_t * result_len);
60
61static int imap_fetch_body(mailmessage * msg_info,
62 char ** result, size_t * result_len);
63
64static int imap_fetch_size(mailmessage * msg_info,
65 size_t * result);
66
67static int imap_get_bodystructure(mailmessage * msg_info,
68 struct mailmime ** result);
69
70static int imap_fetch_section(mailmessage * msg_info,
71 struct mailmime * mime,
72 char ** result, size_t * result_len);
73
74static int imap_fetch_section_header(mailmessage * msg_info,
75 struct mailmime * mime,
76 char ** result,
77 size_t * result_len);
78
79static int imap_fetch_section_mime(mailmessage * msg_info,
80 struct mailmime * mime,
81 char ** result,
82 size_t * result_len);
83
84static int imap_fetch_section_body(mailmessage * msg_info,
85 struct mailmime * mime,
86 char ** result,
87 size_t * result_len);
88
89static int imap_fetch_envelope(mailmessage * msg_info,
90 struct mailimf_fields ** result);
91
92static int imap_get_flags(mailmessage * msg_info,
93 struct mail_flags ** result);
94
95static void imap_flush(mailmessage * msg_info);
96
97static void imap_check(mailmessage * msg_info);
98
99static mailmessage_driver local_imap_message_driver = {
100 .msg_name = "imap",
101
102 .msg_initialize = imap_initialize,
103 .msg_uninitialize = NULL,
104
105 .msg_flush = imap_flush,
106 .msg_check = imap_check,
107
108 .msg_fetch_result_free = imap_fetch_result_free,
109
110 .msg_fetch = imap_fetch,
111 .msg_fetch_header = imap_fetch_header,
112 .msg_fetch_body = imap_fetch_body,
113 .msg_fetch_size = imap_fetch_size,
114 .msg_get_bodystructure = imap_get_bodystructure,
115 .msg_fetch_section = imap_fetch_section,
116 .msg_fetch_section_header = imap_fetch_section_header,
117 .msg_fetch_section_mime = imap_fetch_section_mime,
118 .msg_fetch_section_body = imap_fetch_section_body,
119 .msg_fetch_envelope = imap_fetch_envelope,
120
121 .msg_get_flags = imap_get_flags,
122};
123
124mailmessage_driver * imap_message_driver = &local_imap_message_driver;
125
126static inline struct imap_session_state_data *
127get_session_data(mailmessage * msg)
128{
129 return msg->msg_session->sess_data;
130}
131
132static inline mailimap * get_imap_session(mailmessage * msg)
133{
134 return get_session_data(msg)->imap_session;
135}
136
137
138
139static int imap_initialize(mailmessage * msg_info)
140{
141 char key[PATH_MAX];
142 char * uid;
143 mailimap * imap;
144
145 imap = get_imap_session(msg_info);
146
147 snprintf(key, PATH_MAX, "%u-%u",
148 imap->imap_selection_info->sel_uidvalidity, msg_info->msg_index);
149
150 uid = strdup(key);
151 if (uid == NULL) {
152 return MAIL_ERROR_MEMORY;
153 }
154
155 msg_info->msg_uid = uid;
156
157 return MAIL_NO_ERROR;
158}
159
160
161static void imap_fetch_result_free(mailmessage * msg_info,
162 char * msg)
163{
164 if (msg != NULL) {
165 if (mmap_string_unref(msg) != 0)
166 free(msg);
167 }
168}
169
170
171static void imap_flush(mailmessage * msg_info)
172{
173 if (msg_info->msg_mime != NULL) {
174 mailmime_free(msg_info->msg_mime);
175 msg_info->msg_mime = NULL;
176 }
177}
178
179static void imap_check(mailmessage * msg_info)
180{
181 int r;
182
183 if (msg_info->msg_flags != NULL) {
184 r = mail_flags_store_set(get_session_data(msg_info)->imap_flags_store,
185 msg_info);
186 /* ignore errors */
187 }
188}
189
190static int imap_fetch(mailmessage * msg_info,
191 char ** result,
192 size_t * result_len)
193{
194 int r;
195 struct mailimap_set * set;
196 struct mailimap_fetch_att * fetch_att;
197 struct mailimap_fetch_type * fetch_type;
198 clist * fetch_result;
199 struct mailimap_msg_att * msg_att;
200 struct mailimap_msg_att_item * msg_att_item;
201 char * text;
202 size_t text_length;
203 int res;
204 clistiter * cur;
205 struct mailimap_section * section;
206
207 set = mailimap_set_new_single(msg_info->msg_index);
208 if (set == NULL) {
209 res = MAIL_ERROR_MEMORY;
210 goto err;
211 }
212
213#if 0
214 fetch_att = mailimap_fetch_att_new_rfc822();
215 if (fetch_att == NULL) {
216 res = MAIL_ERROR_MEMORY;
217 goto free_set;
218 }
219
220 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
221 if (fetch_type == NULL) {
222 res = MAIL_ERROR_MEMORY;
223 goto free_fetch_att;
224 }
225
226 r = mailimap_uid_fetch(get_imap_session(msg_info->session), set,
227 fetch_type, &fetch_result);
228
229 mailimap_fetch_type_free(fetch_type);
230#endif
231
232 section = mailimap_section_new(NULL);
233 if (section == NULL) {
234 res = MAIL_ERROR_MEMORY;
235 goto free_set;
236 }
237
238 fetch_att = mailimap_fetch_att_new_body_peek_section(section);
239 if (fetch_att == NULL) {
240 mailimap_section_free(section);
241 res = MAIL_ERROR_MEMORY;
242 goto free_set;
243 }
244
245 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
246 if (fetch_type == NULL) {
247 res = MAIL_ERROR_MEMORY;
248 goto free_fetch_att;
249 }
250
251 r = mailimap_uid_fetch(get_imap_session(msg_info), set,
252 fetch_type, &fetch_result);
253
254 mailimap_fetch_type_free(fetch_type);
255 mailimap_set_free(set);
256
257 switch (r) {
258 case MAILIMAP_NO_ERROR:
259 break;
260 default:
261 return imap_error_to_mail_error(r);
262 }
263
264 if (clist_begin(fetch_result) == NULL) {
265 mailimap_fetch_list_free(fetch_result);
266 return MAIL_ERROR_FETCH;
267 }
268
269 msg_att = clist_begin(fetch_result)->data;
270
271 text = NULL;
272 text_length = 0;
273
274 for(cur = clist_begin(msg_att->att_list) ; cur != NULL ;
275 cur = clist_next(cur)) {
276 msg_att_item = clist_content(cur);
277
278 if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) {
279#if 0
280 if (msg_att_item->msg_att_static->type == MAILIMAP_MSG_ATT_RFC822) {
281 text = msg_att_item->msg_att_static->rfc822;
282 msg_att_item->msg_att_static->rfc822 = NULL;
283 text_length = msg_att_item->msg_att_static->length;
284 }
285#endif
286 if (msg_att_item->att_data.att_static->att_type ==
287 MAILIMAP_MSG_ATT_BODY_SECTION) {
288 text = msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part;
289 /* detach */
290 msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = NULL;
291 text_length =
292 msg_att_item->att_data.att_static->att_data.att_body_section->sec_length;
293 }
294 }
295 }
296
297 mailimap_fetch_list_free(fetch_result);
298
299 if (text == NULL)
300 return MAIL_ERROR_FETCH;
301
302 * result = text;
303 * result_len = text_length;
304
305 return MAIL_NO_ERROR;
306
307 free_fetch_att:
308 mailimap_fetch_att_free(fetch_att);
309 free_set:
310 mailimap_set_free(set);
311 err:
312 return res;
313}
314
315static int imap_fetch_header(mailmessage * msg_info,
316 char ** result,
317 size_t * result_len)
318{
319 int r;
320 struct mailimap_set * set;
321 struct mailimap_fetch_att * fetch_att;
322 struct mailimap_fetch_type * fetch_type;
323 clist * fetch_result;
324 struct mailimap_msg_att * msg_att;
325 struct mailimap_msg_att_item * msg_att_item;
326 char * text;
327 size_t text_length;
328 int res;
329 clistiter * cur;
330 struct mailimap_section * section;
331
332 set = mailimap_set_new_single(msg_info->msg_index);
333 if (set == NULL) {
334 res = MAIL_ERROR_MEMORY;
335 goto err;
336 }
337
338#if 0
339 fetch_att = mailimap_fetch_att_new_rfc822_header();
340 if (fetch_att == NULL) {
341 res = MAIL_ERROR_MEMORY;
342 goto free_set;
343 }
344
345 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
346 if (fetch_type == NULL) {
347 res = MAIL_ERROR_MEMORY;
348 goto free_fetch_att;
349 }
350
351 r = mailimap_uid_fetch(get_imap_session(msg_info->session),
352 set, fetch_type, &fetch_result);
353
354 mailimap_fetch_type_free(fetch_type);
355#endif
356
357 section = mailimap_section_new_header();
358 if (section == NULL) {
359 res = MAIL_ERROR_MEMORY;
360 goto free_set;
361 }
362
363 fetch_att = mailimap_fetch_att_new_body_peek_section(section);
364 if (fetch_att == NULL) {
365 mailimap_section_free(section);
366 res = MAIL_ERROR_MEMORY;
367 goto free_set;
368 }
369
370 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
371 if (fetch_type == NULL) {
372 res = MAIL_ERROR_MEMORY;
373 goto free_fetch_att;
374 }
375
376 r = mailimap_uid_fetch(get_imap_session(msg_info), set,
377 fetch_type, &fetch_result);
378
379 mailimap_fetch_type_free(fetch_type);
380 mailimap_set_free(set);
381
382 switch (r) {
383 case MAILIMAP_NO_ERROR:
384 break;
385 default:
386 return imap_error_to_mail_error(r);
387 }
388
389 if (clist_begin(fetch_result) == NULL) {
390 mailimap_fetch_list_free(fetch_result);
391 return MAIL_ERROR_FETCH;
392 }
393
394 msg_att = clist_begin(fetch_result)->data;
395
396 text = NULL;
397 text_length = 0;
398
399 for(cur = clist_begin(msg_att->att_list) ; cur != NULL ;
400 cur = clist_next(cur)) {
401 msg_att_item = clist_content(cur);
402
403 if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) {
404#if 0
405 if (msg_att_item->msg_att_static->type ==
406 MAILIMAP_MSG_ATT_RFC822_HEADER) {
407 text = msg_att_item->msg_att_static->rfc822_header;
408 msg_att_item->msg_att_static->rfc822_header = NULL;
409 text_length = msg_att_item->msg_att_static->length;
410 }
411#endif
412 if (msg_att_item->att_data.att_static->att_type ==
413 MAILIMAP_MSG_ATT_BODY_SECTION) {
414 text = msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part;
415 msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = NULL;
416 text_length =
417 msg_att_item->att_data.att_static->att_data.att_body_section->sec_length;
418 }
419 }
420 }
421
422 mailimap_fetch_list_free(fetch_result);
423
424 if (text == NULL)
425 return MAIL_ERROR_FETCH;
426
427 * result = text;
428 * result_len = text_length;
429
430 return MAIL_NO_ERROR;
431
432 free_fetch_att:
433 mailimap_fetch_att_free(fetch_att);
434 free_set:
435 mailimap_set_free(set);
436 err:
437 return res;
438}
439
440static int imap_fetch_body(mailmessage * msg_info,
441 char ** result, size_t * result_len)
442{
443 int r;
444 struct mailimap_set * set;
445 struct mailimap_fetch_att * fetch_att;
446 struct mailimap_fetch_type * fetch_type;
447 clist * fetch_result;
448 struct mailimap_msg_att * msg_att;
449 struct mailimap_msg_att_item * msg_att_item;
450 char * text;
451 size_t text_length;
452 int res;
453 clistiter * cur;
454 struct mailimap_section * section;
455
456 set = mailimap_set_new_single(msg_info->msg_index);
457 if (set == NULL) {
458 res = MAIL_ERROR_MEMORY;
459 goto err;
460 }
461
462#if 0
463 fetch_att = mailimap_fetch_att_new_rfc822_text();
464 if (fetch_att == NULL) {
465 res = MAIL_ERROR_MEMORY;
466 goto free_set;
467 }
468
469 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
470 if (fetch_type == NULL) {
471 res = MAIL_ERROR_MEMORY;
472 goto free_fetch_att;
473 }
474
475 r = mailimap_uid_fetch(get_imap_session(msg_info->session), set,
476 fetch_type, &fetch_result);
477
478 mailimap_fetch_type_free(fetch_type);
479#endif
480 section = mailimap_section_new_text();
481 if (section == NULL) {
482 res = MAIL_ERROR_MEMORY;
483 goto free_set;
484 }
485
486 fetch_att = mailimap_fetch_att_new_body_peek_section(section);
487 if (fetch_att == NULL) {
488 mailimap_section_free(section);
489 res = MAIL_ERROR_MEMORY;
490 goto free_set;
491 }
492
493 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
494 if (fetch_type == NULL) {
495 res = MAIL_ERROR_MEMORY;
496 goto free_fetch_att;
497 }
498
499 r = mailimap_uid_fetch(get_imap_session(msg_info), set,
500 fetch_type, &fetch_result);
501
502 mailimap_fetch_type_free(fetch_type);
503 mailimap_set_free(set);
504
505 switch (r) {
506 case MAILIMAP_NO_ERROR:
507 break;
508 default:
509 return imap_error_to_mail_error(r);
510 }
511
512 cur = clist_begin(fetch_result);
513 if (cur == NULL) {
514 mailimap_fetch_list_free(fetch_result);
515 return MAIL_ERROR_FETCH;
516 }
517
518 msg_att = clist_content(cur);
519
520 text = NULL;
521 text_length = 0;
522
523 for(cur = clist_begin(msg_att->att_list) ; cur != NULL ;
524 cur = clist_next(cur)) {
525 msg_att_item = clist_content(cur);
526
527 if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) {
528#if 0
529 if (msg_att_item->msg_att_static->type ==
530 MAILIMAP_MSG_ATT_RFC822_TEXT) {
531 text = msg_att_item->msg_att_static->rfc822_text;
532 msg_att_item->msg_att_static->rfc822_text = NULL;
533 text_length = msg_att_item->msg_att_static->length;
534 }
535#endif
536 if (msg_att_item->att_data.att_static->att_type ==
537 MAILIMAP_MSG_ATT_BODY_SECTION) {
538 text = msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part;
539 msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = NULL;
540 text_length =
541 msg_att_item->att_data.att_static->att_data.att_body_section->sec_length;
542 }
543 }
544 }
545
546 mailimap_fetch_list_free(fetch_result);
547
548 if (text == NULL)
549 return MAIL_ERROR_FETCH;
550
551 * result = text;
552 * result_len = text_length;
553
554 return MAIL_NO_ERROR;
555
556 free_fetch_att:
557 mailimap_fetch_att_free(fetch_att);
558 free_set:
559 mailimap_set_free(set);
560 err:
561 return res;
562}
563
564static int imap_fetch_size(mailmessage * msg_info,
565 size_t * result)
566{
567 int r;
568 struct mailimap_set * set;
569 struct mailimap_fetch_att * fetch_att;
570 struct mailimap_fetch_type * fetch_type;
571 clist * fetch_result;
572 struct mailimap_msg_att * msg_att;
573 struct mailimap_msg_att_item * msg_att_item;
574 size_t size;
575 int res;
576 clistiter * cur;
577
578 set = mailimap_set_new_single(msg_info->msg_index);
579 if (set == NULL) {
580 res = MAIL_ERROR_MEMORY;
581 goto err;
582 }
583
584 fetch_att = mailimap_fetch_att_new_rfc822_size();
585 if (fetch_att == NULL) {
586 res = MAIL_ERROR_MEMORY;
587 goto free_set;
588 }
589
590 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
591 if (fetch_type == NULL) {
592 res = MAIL_ERROR_MEMORY;
593 goto free_fetch_att;
594 }
595
596 r = mailimap_uid_fetch(get_imap_session(msg_info), set,
597 fetch_type, &fetch_result);
598
599 mailimap_fetch_type_free(fetch_type);
600 mailimap_set_free(set);
601
602 switch (r) {
603 case MAILIMAP_ERROR_BAD_STATE:
604 return MAIL_ERROR_BAD_STATE;
605 case MAILIMAP_ERROR_STREAM:
606 return MAIL_ERROR_STREAM;
607 case MAILIMAP_NO_ERROR:
608 break;
609 default:
610 return MAIL_ERROR_FETCH;
611 }
612
613 if (clist_begin(fetch_result) == NULL) {
614 mailimap_fetch_list_free(fetch_result);
615 return MAIL_ERROR_FETCH;
616 }
617
618 msg_att = clist_begin(fetch_result)->data;
619
620 for(cur = clist_begin(msg_att->att_list) ; cur != NULL ;
621 cur = clist_next(cur)) {
622 msg_att_item = clist_content(cur);
623
624 if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) {
625
626 if (msg_att_item->att_data.att_static->att_type ==
627 MAILIMAP_MSG_ATT_RFC822_SIZE) {
628 size = msg_att_item->att_data.att_static->att_data.att_rfc822_size;
629
630 * result = size;
631
632 mailimap_fetch_list_free(fetch_result);
633 return MAIL_NO_ERROR;
634 }
635 }
636 }
637
638 mailimap_fetch_list_free(fetch_result);
639
640 return MAIL_ERROR_FETCH;
641
642 free_fetch_att:
643 mailimap_fetch_att_free(fetch_att);
644 free_set:
645 mailimap_set_free(set);
646 err:
647 return res;
648}
649
650static int imap_get_bodystructure(mailmessage * msg_info,
651 struct mailmime ** result)
652{
653 int r;
654 struct mailimap_set * set;
655 struct mailimap_fetch_att * fetch_att;
656 struct mailimap_fetch_type * fetch_type;
657 clist * fetch_result;
658 struct mailimap_msg_att * msg_att;
659 struct mailimap_body * imap_body;
660 struct mailmime * body;
661 int res;
662 struct mailimf_fields * fields;
663 struct mailmime * new_body;
664 struct mailmime_content * content_message;
665 struct mailimap_envelope * envelope;
666 uint32_t uid;
667 char * references;
668 size_t ref_size;
669 clistiter * cur;
670
671 if (msg_info->msg_mime != NULL) {
672 * result = msg_info->msg_mime;
673
674 return MAIL_NO_ERROR;
675 }
676
677 set = mailimap_set_new_single(msg_info->msg_index);
678 if (set == NULL) {
679 res = MAIL_ERROR_MEMORY;
680 goto err;
681 }
682
683 fetch_type = mailimap_fetch_type_new_fetch_att_list_empty();
684 if (fetch_type == NULL) {
685 res = MAIL_ERROR_MEMORY;
686 goto free_set;
687 }
688
689 fetch_att = mailimap_fetch_att_new_uid();
690 if (fetch_att == NULL) {
691 res = MAIL_ERROR_MEMORY;
692 goto free_fetch_type;
693 }
694
695 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
696 if (r != MAILIMAP_NO_ERROR) {
697 mailimap_fetch_att_free(fetch_att);
698 res = MAIL_ERROR_MEMORY;
699 goto free_fetch_type;
700 }
701
702 fetch_att = mailimap_fetch_att_new_bodystructure();
703 if (fetch_att == NULL) {
704 res = MAIL_ERROR_MEMORY;
705 goto free_fetch_type;
706 }
707
708 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
709 if (r != MAILIMAP_NO_ERROR) {
710 mailimap_fetch_att_free(fetch_att);
711 res = MAIL_ERROR_MEMORY;
712 goto free_fetch_type;
713 }
714
715 r = imap_add_envelope_fetch_att(fetch_type);
716 if (r != MAIL_NO_ERROR) {
717 res = r;
718 goto free_fetch_type;
719 }
720
721
722 r = mailimap_uid_fetch(get_imap_session(msg_info), set,
723 fetch_type, &fetch_result);
724
725 mailimap_fetch_type_free(fetch_type);
726 mailimap_set_free(set);
727
728 switch (r) {
729 case MAILIMAP_NO_ERROR:
730 break;
731 default:
732 return imap_error_to_mail_error(r);
733 }
734
735 cur = clist_begin(fetch_result);
736 if (cur == NULL) {
737 mailimap_fetch_list_free(fetch_result);
738 return MAIL_ERROR_FETCH;
739 }
740
741 msg_att = clist_content(cur);
742
743 uid = 0;
744 references = NULL;
745 ref_size = 0;
746 imap_body = NULL;
747 envelope = NULL;
748
749 r = imap_get_msg_att_info(msg_att,
750 &uid, &envelope, &references, &ref_size, NULL, &imap_body);
751 if (r != MAIL_NO_ERROR) {
752 mailimap_fetch_list_free(fetch_result);
753 res = r;
754 goto err;
755 }
756
757 if (uid != msg_info->msg_index) {
758 mailimap_fetch_list_free(fetch_result);
759 res = MAIL_ERROR_MSG_NOT_FOUND;
760 goto err;
761 }
762
763 if (imap_body == NULL) {
764 mailimap_fetch_list_free(fetch_result);
765 res = MAIL_ERROR_FETCH;
766 goto err;
767 }
768
769 r = imap_body_to_body(imap_body, &body);
770 if (r != MAIL_NO_ERROR) {
771 mailimap_fetch_list_free(fetch_result);
772 res = r;
773 goto err;
774 }
775
776 fields = NULL;
777 if (envelope != NULL) {
778 r = imap_env_to_fields(envelope, references, ref_size, &fields);
779 if (r != MAIL_NO_ERROR) {
780 mailmime_free(body);
781 mailimap_fetch_list_free(fetch_result);
782 res = r;
783 goto err;
784 }
785 }
786
787 content_message = mailmime_get_content_message();
788 if (content_message == NULL) {
789 if (fields != NULL)
790 mailimf_fields_free(fields);
791 mailmime_free(body);
792 mailimap_fetch_list_free(fetch_result);
793 res = MAIL_ERROR_MEMORY;
794 goto err;
795 }
796
797 new_body = mailmime_new(MAILMIME_MESSAGE, NULL,
798 0, NULL, content_message,
799 NULL, NULL, NULL, NULL, fields, body);
800
801 if (new_body == NULL) {
802 mailmime_content_free(content_message);
803 if (fields != NULL)
804 mailimf_fields_free(fields);
805 mailmime_free(body);
806 mailimap_fetch_list_free(fetch_result);
807 res = MAIL_ERROR_MEMORY;
808 goto err;
809 }
810 msg_info->msg_mime = new_body;
811
812 mailimap_fetch_list_free(fetch_result);
813
814 * result = new_body;
815
816 return MAIL_NO_ERROR;
817
818 free_fetch_type:
819 mailimap_fetch_type_free(fetch_type);
820 free_set:
821 mailimap_set_free(set);
822 err:
823 return res;
824}
825
826static int
827fetch_imap(mailmessage * msg,
828 struct mailimap_fetch_type * fetch_type,
829 char ** result, size_t * result_len)
830{
831 int r;
832 struct mailimap_msg_att * msg_att;
833 struct mailimap_msg_att_item * msg_att_item;
834 clist * fetch_result;
835 struct mailimap_set * set;
836 char * text;
837 size_t text_length;
838 clistiter * cur;
839
840 set = mailimap_set_new_single(msg->msg_index);
841 if (set == NULL)
842 return MAIL_ERROR_MEMORY;
843
844 r = mailimap_uid_fetch(get_imap_session(msg), set,
845 fetch_type, &fetch_result);
846
847 mailimap_set_free(set);
848
849 switch (r) {
850 case MAILIMAP_NO_ERROR:
851 break;
852 default:
853 return imap_error_to_mail_error(r);
854 }
855
856 if (clist_begin(fetch_result) == NULL) {
857 mailimap_fetch_list_free(fetch_result);
858 return MAIL_ERROR_FETCH;
859 }
860
861 msg_att = clist_begin(fetch_result)->data;
862
863 text = NULL;
864 text_length = 0;
865
866 for(cur = clist_begin(msg_att->att_list) ; cur != NULL ;
867 cur = clist_next(cur)) {
868 msg_att_item = clist_content(cur);
869
870 if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) {
871
872 if (msg_att_item->att_data.att_static->att_type ==
873 MAILIMAP_MSG_ATT_BODY_SECTION) {
874 text = msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part;
875 msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = NULL;
876 text_length =
877 msg_att_item->att_data.att_static->att_data.att_body_section->sec_length;
878 }
879 }
880 }
881
882 mailimap_fetch_list_free(fetch_result);
883
884 if (text == NULL)
885 return MAIL_ERROR_FETCH;
886
887 * result = text;
888 * result_len = text_length;
889
890 return MAIL_NO_ERROR;
891}
892
893
894static int imap_fetch_section(mailmessage * msg_info,
895 struct mailmime * mime,
896 char ** result, size_t * result_len)
897{
898 struct mailimap_section * section;
899 struct mailimap_fetch_att * fetch_att;
900 int r;
901 struct mailimap_fetch_type * fetch_type;
902 char * text;
903 size_t text_length;
904 struct mailmime_section * part;
905
906 if (mime->mm_parent == NULL)
907 return imap_fetch(msg_info, result, result_len);
908
909 r = mailmime_get_section_id(mime, &part);
910 if (r != MAILIMF_NO_ERROR)
911 return maildriver_imf_error_to_mail_error(r);
912
913 r = section_to_imap_section(part, IMAP_SECTION_MESSAGE, &section);
914 mailmime_section_free(part);
915 if (r != MAIL_NO_ERROR)
916 return r;
917
918 fetch_att = mailimap_fetch_att_new_body_peek_section(section);
919 if (fetch_att == NULL) {
920 mailimap_section_free(section);
921 return MAIL_ERROR_MEMORY;
922 }
923
924 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
925 if (fetch_type == NULL) {
926 mailimap_fetch_att_free(fetch_att);
927 return MAIL_ERROR_MEMORY;
928 }
929
930 r = fetch_imap(msg_info, fetch_type, &text, &text_length);
931
932 mailimap_fetch_type_free(fetch_type);
933
934 if (r != MAIL_NO_ERROR)
935 return r;
936
937 * result = text;
938 * result_len = text_length;
939
940 return MAIL_NO_ERROR;
941}
942
943static int imap_fetch_section_header(mailmessage * msg_info,
944 struct mailmime * mime,
945 char ** result,
946 size_t * result_len)
947{
948 struct mailimap_section * section;
949 struct mailimap_fetch_att * fetch_att;
950 int r;
951 struct mailimap_fetch_type * fetch_type;
952 char * text;
953 size_t text_length;
954 struct mailmime_section * part;
955
956 if (mime->mm_parent == NULL)
957 return imap_fetch_header(msg_info, result, result_len);
958
959 r = mailmime_get_section_id(mime, &part);
960 if (r != MAILIMF_NO_ERROR)
961 return maildriver_imf_error_to_mail_error(r);
962
963 r = section_to_imap_section(part, IMAP_SECTION_HEADER, &section);
964 mailmime_section_free(part);
965 if (r != MAIL_NO_ERROR)
966 return r;
967
968 fetch_att = mailimap_fetch_att_new_body_peek_section(section);
969 if (fetch_att == NULL) {
970 mailimap_section_free(section);
971 return MAIL_ERROR_MEMORY;
972 }
973
974 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
975 if (fetch_type == NULL) {
976 mailimap_fetch_att_free(fetch_att);
977 return MAIL_ERROR_MEMORY;
978 }
979
980 r = fetch_imap(msg_info, fetch_type, &text, &text_length);
981 mailimap_fetch_type_free(fetch_type);
982
983 if (r != MAIL_NO_ERROR)
984 return r;
985
986 * result = text;
987 * result_len = text_length;
988
989 return MAIL_NO_ERROR;
990}
991
992static int imap_fetch_section_mime(mailmessage * msg_info,
993 struct mailmime * mime,
994 char ** result,
995 size_t * result_len)
996{
997 struct mailimap_section * section;
998 struct mailimap_fetch_att * fetch_att;
999 int r;
1000 struct mailimap_fetch_type * fetch_type;
1001 char * text;
1002 size_t text_length;
1003 struct mailmime_section * part;
1004
1005 if (mime->mm_parent == NULL)
1006 return MAIL_ERROR_INVAL;
1007
1008 if (mime->mm_parent->mm_parent == NULL)
1009 return imap_fetch_header(msg_info, result, result_len);
1010
1011 r = mailmime_get_section_id(mime, &part);
1012 if (r != MAILIMF_NO_ERROR)
1013 return maildriver_imf_error_to_mail_error(r);
1014
1015 r = section_to_imap_section(part, IMAP_SECTION_MIME, &section);
1016 mailmime_section_free(part);
1017 if (r != MAIL_NO_ERROR)
1018 return MAIL_ERROR_MEMORY;
1019
1020 fetch_att = mailimap_fetch_att_new_body_peek_section(section);
1021 if (fetch_att == NULL) {
1022 mailimap_section_free(section);
1023 return MAIL_ERROR_MEMORY;
1024 }
1025
1026 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
1027 if (fetch_type == NULL) {
1028 mailimap_fetch_att_free(fetch_att);
1029 return MAIL_ERROR_MEMORY;
1030 }
1031
1032 r = fetch_imap(msg_info, fetch_type, &text, &text_length);
1033
1034 mailimap_fetch_type_free(fetch_type);
1035
1036 if (r != MAIL_NO_ERROR)
1037 return r;
1038
1039 * result = text;
1040 * result_len = text_length;
1041
1042 return MAIL_NO_ERROR;
1043}
1044
1045static int imap_fetch_section_body(mailmessage * msg_info,
1046 struct mailmime * mime,
1047 char ** result,
1048 size_t * result_len)
1049{
1050 struct mailimap_section * section;
1051 struct mailimap_fetch_att * fetch_att;
1052 int r;
1053 struct mailimap_fetch_type * fetch_type;
1054 char * text;
1055 size_t text_length;
1056 struct mailmime_section * part;
1057
1058 if (mime->mm_parent == NULL)
1059 return imap_fetch_body(msg_info, result, result_len);
1060
1061 if (mime->mm_parent->mm_parent == NULL)
1062 return imap_fetch_body(msg_info, result, result_len);
1063
1064 r = mailmime_get_section_id(mime, &part);
1065 if (r != MAILIMF_NO_ERROR)
1066 return maildriver_imf_error_to_mail_error(r);
1067
1068 r = section_to_imap_section(part, IMAP_SECTION_BODY, &section);
1069 mailmime_section_free(part);
1070 if (r != MAIL_NO_ERROR)
1071 return MAIL_ERROR_MEMORY;
1072
1073 fetch_att = mailimap_fetch_att_new_body_peek_section(section);
1074 if (fetch_att == NULL) {
1075 mailimap_section_free(section);
1076 return MAIL_ERROR_MEMORY;
1077 }
1078
1079 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
1080 if (fetch_type == NULL) {
1081 mailimap_fetch_att_free(fetch_att);
1082 return MAIL_ERROR_MEMORY;
1083 }
1084
1085 r = fetch_imap(msg_info, fetch_type, &text, &text_length);
1086
1087 mailimap_fetch_type_free(fetch_type);
1088
1089 if (r != MAIL_NO_ERROR)
1090 return r;
1091
1092 * result = text;
1093 * result_len = text_length;
1094
1095 return MAIL_NO_ERROR;
1096}
1097
1098static int imap_get_flags(mailmessage * msg_info,
1099 struct mail_flags ** result)
1100{
1101 int r;
1102 struct mail_flags * flags;
1103
1104 if (msg_info->msg_flags != NULL) {
1105 * result = msg_info->msg_flags;
1106 return MAIL_NO_ERROR;
1107 }
1108
1109 flags = mail_flags_store_get(get_session_data(msg_info)->imap_flags_store,
1110 msg_info->msg_index);
1111
1112 if (flags == NULL) {
1113 r = imap_fetch_flags(get_imap_session(msg_info),
1114 msg_info->msg_index, &flags);
1115 if (r != MAIL_NO_ERROR)
1116 return r;
1117 }
1118
1119 msg_info->msg_flags = flags;
1120
1121 * result = flags;
1122
1123 return MAIL_NO_ERROR;
1124}
1125
1126static int imap_fetch_envelope(mailmessage * msg_info,
1127 struct mailimf_fields ** result)
1128{
1129 int r;
1130 struct mailimap_set * set;
1131 struct mailimap_fetch_att * fetch_att;
1132 struct mailimap_fetch_type * fetch_type;
1133 clist * fetch_result;
1134 struct mailimap_msg_att * msg_att;
1135 int res;
1136 struct mailimf_fields * fields;
1137 struct mailimap_envelope * envelope;
1138 uint32_t uid;
1139 char * references;
1140 size_t ref_size;
1141
1142 set = mailimap_set_new_single(msg_info->msg_index);
1143 if (set == NULL) {
1144 res = MAIL_ERROR_MEMORY;
1145 goto err;
1146 }
1147
1148 fetch_type = mailimap_fetch_type_new_fetch_att_list_empty();
1149 if (fetch_type == NULL) {
1150 res = MAIL_ERROR_MEMORY;
1151 goto free_set;
1152 }
1153
1154 fetch_att = mailimap_fetch_att_new_uid();
1155 if (fetch_att == NULL) {
1156 res = MAIL_ERROR_MEMORY;
1157 goto free_fetch_type;
1158 }
1159
1160 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
1161 if (r != MAILIMAP_NO_ERROR) {
1162 mailimap_fetch_att_free(fetch_att);
1163 res = MAIL_ERROR_MEMORY;
1164 goto free_fetch_type;
1165 }
1166
1167 r = imap_add_envelope_fetch_att(fetch_type);
1168 if (r != MAIL_NO_ERROR) {
1169 res = r;
1170 goto free_fetch_type;
1171 }
1172
1173 r = mailimap_uid_fetch(get_imap_session(msg_info), set,
1174 fetch_type, &fetch_result);
1175
1176 mailimap_fetch_type_free(fetch_type);
1177 mailimap_set_free(set);
1178
1179 switch (r) {
1180 case MAILIMAP_NO_ERROR:
1181 break;
1182 default:
1183 return imap_error_to_mail_error(r);
1184 }
1185
1186 if (clist_begin(fetch_result) == NULL) {
1187 mailimap_fetch_list_free(fetch_result);
1188 return MAIL_ERROR_FETCH;
1189 }
1190
1191 msg_att = clist_begin(fetch_result)->data;
1192
1193 uid = 0;
1194 references = NULL;
1195 ref_size = 0;
1196 envelope = NULL;
1197
1198 r = imap_get_msg_att_info(msg_att,
1199 &uid,
1200 &envelope,
1201 &references,
1202 &ref_size,
1203 NULL,
1204 NULL);
1205 if (r != MAIL_NO_ERROR) {
1206 mailimap_fetch_list_free(fetch_result);
1207 res = r;
1208 goto err;
1209 }
1210
1211 if (uid != msg_info->msg_index) {
1212 mailimap_fetch_list_free(fetch_result);
1213 res = MAIL_ERROR_MSG_NOT_FOUND;
1214 goto err;
1215 }
1216
1217 fields = NULL;
1218 if (envelope != NULL) {
1219 r = imap_env_to_fields(envelope, references, ref_size, &fields);
1220 if (r != MAIL_NO_ERROR) {
1221 mailimap_fetch_list_free(fetch_result);
1222 res = r;
1223 goto err;
1224 }
1225 }
1226
1227 mailimap_fetch_list_free(fetch_result);
1228
1229 * result = fields;
1230
1231 return MAIL_NO_ERROR;
1232
1233 free_fetch_type:
1234 mailimap_fetch_type_free(fetch_type);
1235 free_set:
1236 mailimap_set_free(set);
1237 err:
1238 return res;
1239}
diff --git a/kmicromail/libetpan/generic/imapdriver_message.h b/kmicromail/libetpan/generic/imapdriver_message.h
new file mode 100644
index 0000000..9142633
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef IMAPDRIVER_MESSAGE_H
37
38#define IMAPDRIVER_MESSAGE_H
39
40#include <libetpan/imapdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * imap_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/imapdriver_tools.c b/kmicromail/libetpan/generic/imapdriver_tools.c
new file mode 100644
index 0000000..3d737f3
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_tools.c
@@ -0,0 +1,3599 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "imapdriver_tools.h"
37
38#include "maildriver.h"
39
40#include <stdlib.h>
41#include <string.h>
42
43#include "mail.h"
44#include "imapdriver_types.h"
45#include "maildriver_tools.h"
46#include "generic_cache.h"
47#include "mailmessage.h"
48#include "mail_cache_db.h"
49
50
51
52static inline struct imap_session_state_data *
53session_get_data(mailsession * session)
54{
55 return session->sess_data;
56}
57
58static inline struct imap_cached_session_state_data *
59cached_session_get_data(mailsession * session)
60{
61 return session->sess_data;
62}
63
64static inline mailsession *
65cached_session_get_ancestor(mailsession * session)
66{
67 return cached_session_get_data(session)->imap_ancestor;
68}
69
70static inline struct imap_session_state_data *
71cached_session_get_ancestor_data(mailsession * session)
72{
73 return session_get_data(cached_session_get_ancestor(session));
74}
75
76static inline mailimap *
77cached_session_get_imap_session(mailsession * session)
78{
79 return cached_session_get_ancestor_data(session)->imap_session;
80}
81
82static int imap_flags_to_flags(struct mailimap_msg_att_dynamic * att_dyn,
83 struct mail_flags ** result);
84
85
86int imap_error_to_mail_error(int error)
87{
88 switch (error) {
89 case MAILIMAP_NO_ERROR:
90 return MAIL_NO_ERROR;
91
92 case MAILIMAP_NO_ERROR_AUTHENTICATED:
93 return MAIL_NO_ERROR_AUTHENTICATED;
94
95 case MAILIMAP_NO_ERROR_NON_AUTHENTICATED:
96 return MAIL_NO_ERROR_NON_AUTHENTICATED;
97
98 case MAILIMAP_ERROR_BAD_STATE:
99 return MAIL_ERROR_BAD_STATE;
100
101 case MAILIMAP_ERROR_STREAM:
102 return MAIL_ERROR_STREAM;
103
104 case MAILIMAP_ERROR_PARSE:
105 return MAIL_ERROR_PARSE;
106
107 case MAILIMAP_ERROR_CONNECTION_REFUSED:
108 return MAIL_ERROR_CONNECT;
109
110 case MAILIMAP_ERROR_MEMORY:
111 return MAIL_ERROR_MEMORY;
112
113 case MAILIMAP_ERROR_FATAL:
114 return MAIL_ERROR_FATAL;
115
116 case MAILIMAP_ERROR_PROTOCOL:
117 return MAIL_ERROR_PROTOCOL;
118
119 case MAILIMAP_ERROR_DONT_ACCEPT_CONNECTION:
120 return MAIL_ERROR_CONNECT;
121
122 case MAILIMAP_ERROR_APPEND:
123 return MAIL_ERROR_APPEND;
124
125 case MAILIMAP_ERROR_NOOP:
126 return MAIL_ERROR_NOOP;
127
128 case MAILIMAP_ERROR_LOGOUT:
129 return MAIL_ERROR_LOGOUT;
130
131 case MAILIMAP_ERROR_CAPABILITY:
132 return MAIL_ERROR_CAPABILITY;
133
134 case MAILIMAP_ERROR_CHECK:
135 return MAIL_ERROR_CHECK;
136
137 case MAILIMAP_ERROR_CLOSE:
138 return MAIL_ERROR_CLOSE;
139
140 case MAILIMAP_ERROR_EXPUNGE:
141 return MAIL_ERROR_EXPUNGE;
142
143 case MAILIMAP_ERROR_COPY:
144 case MAILIMAP_ERROR_UID_COPY:
145 return MAIL_ERROR_COPY;
146
147 case MAILIMAP_ERROR_CREATE:
148 return MAIL_ERROR_CREATE;
149
150 case MAILIMAP_ERROR_DELETE:
151 return MAIL_ERROR_DELETE;
152
153 case MAILIMAP_ERROR_EXAMINE:
154 return MAIL_ERROR_EXAMINE;
155
156 case MAILIMAP_ERROR_FETCH:
157 case MAILIMAP_ERROR_UID_FETCH:
158 return MAIL_ERROR_FETCH;
159
160 case MAILIMAP_ERROR_LIST:
161 return MAIL_ERROR_LIST;
162
163 case MAILIMAP_ERROR_LOGIN:
164 return MAIL_ERROR_LOGIN;
165
166 case MAILIMAP_ERROR_LSUB:
167 return MAIL_ERROR_LSUB;
168
169 case MAILIMAP_ERROR_RENAME:
170 return MAIL_ERROR_RENAME;
171
172 case MAILIMAP_ERROR_SEARCH:
173 case MAILIMAP_ERROR_UID_SEARCH:
174 return MAIL_ERROR_SEARCH;
175
176 case MAILIMAP_ERROR_SELECT:
177 return MAIL_ERROR_SELECT;
178
179 case MAILIMAP_ERROR_STATUS:
180 return MAIL_ERROR_STATUS;
181
182 case MAILIMAP_ERROR_STORE:
183 case MAILIMAP_ERROR_UID_STORE:
184 return MAIL_ERROR_STORE;
185
186 case MAILIMAP_ERROR_SUBSCRIBE:
187 return MAIL_ERROR_SUBSCRIBE;
188
189 case MAILIMAP_ERROR_UNSUBSCRIBE:
190 return MAIL_ERROR_UNSUBSCRIBE;
191
192 case MAILIMAP_ERROR_STARTTLS:
193 return MAIL_ERROR_STARTTLS;
194
195 case MAILIMAP_ERROR_INVAL:
196 return MAIL_ERROR_INVAL;
197
198 default:
199 return MAIL_ERROR_INVAL;
200 }
201}
202
203
204
205
206
207static int
208imap_body_parameter_to_content(struct mailimap_body_fld_param *
209 body_parameter,
210 char * subtype,
211 struct mailmime_type * mime_type,
212 struct mailmime_content ** result);
213
214static int
215imap_body_type_text_to_content_type(char * subtype,
216 struct mailimap_body_fld_param *
217 body_parameter,
218 struct mailmime_content ** result);
219
220
221int imap_list_to_list(clist * imap_list, struct mail_list ** result)
222{
223 clistiter * cur;
224 clist * list;
225 struct mail_list * resp;
226 int r;
227 int res;
228
229 list = clist_new();
230 if (list == NULL) {
231 res = MAIL_ERROR_MEMORY;
232 goto err;
233 }
234
235 for(cur = clist_begin(imap_list) ; cur != NULL ; cur = clist_next(cur)) {
236 struct mailimap_mailbox_list * mb_list;
237 char * new_mb;
238
239 mb_list = clist_content(cur);
240
241 new_mb = strdup(mb_list->mb_name);
242 if (new_mb == NULL) {
243 res = MAIL_ERROR_MEMORY;
244 goto free_list;
245 }
246
247 r = clist_append(list, new_mb);
248 if (r != 0) {
249 free(new_mb);
250 res = MAIL_ERROR_MEMORY;
251 goto free_list;
252 }
253 }
254
255 resp = mail_list_new(list);
256 if (resp == NULL) {
257 res = MAIL_ERROR_MEMORY;
258 goto free_list;
259 }
260
261 * result = resp;
262
263 return MAIL_NO_ERROR;
264
265 free_list:
266 clist_foreach(list, (clist_func) free, NULL);
267 clist_free(list);
268 err:
269 return res;
270}
271
272int
273section_to_imap_section(struct mailmime_section * section, int type,
274 struct mailimap_section ** result)
275{
276 struct mailimap_section_part * section_part;
277 struct mailimap_section * imap_section;
278 clist * list;
279 clistiter * cur;
280 int r;
281 int res;
282
283 list = clist_new();
284 if (list == NULL) {
285 res = MAIL_ERROR_MEMORY;
286 goto err;
287 }
288
289 for(cur = clist_begin(section->sec_list) ; cur != NULL ;
290 cur = clist_next(cur)) {
291 uint32_t value;
292 uint32_t * id;
293
294 value = * (uint32_t *) clist_content(cur);
295 id = malloc(sizeof(* id));
296 if (id == NULL) {
297 res = MAIL_ERROR_MEMORY;
298 goto free_list;
299 }
300 * id = value;
301 r = clist_append(list, id);
302 if (r != 0) {
303 res = MAIL_ERROR_MEMORY;
304 free(id);
305 goto free_list;
306 }
307 }
308
309 section_part = mailimap_section_part_new(list);
310 if (section_part == NULL) {
311 res = MAIL_ERROR_MEMORY;
312 goto free_list;
313 }
314
315 imap_section = NULL;
316
317 switch (type) {
318 case IMAP_SECTION_MESSAGE:
319 imap_section = mailimap_section_new_part(section_part);
320 break;
321 case IMAP_SECTION_HEADER:
322 imap_section = mailimap_section_new_part_header(section_part);
323 break;
324 case IMAP_SECTION_MIME:
325 imap_section = mailimap_section_new_part_mime(section_part);
326 break;
327 case IMAP_SECTION_BODY:
328 imap_section = mailimap_section_new_part_text(section_part);
329 break;
330 }
331
332 if (imap_section == NULL) {
333 res = MAIL_ERROR_MEMORY;
334 goto free_part;
335 }
336
337 * result = imap_section;
338
339 return MAIL_NO_ERROR;
340
341 free_part:
342 mailimap_section_part_free(section_part);
343 free_list:
344 if (list != NULL) {
345 clist_foreach(list, (clist_func) free, NULL);
346 clist_free(list);
347 }
348 err:
349 return res;
350}
351
352
353
354static int
355imap_body_media_basic_to_content_type(struct mailimap_media_basic *
356 media_basic,
357 struct mailimap_body_fld_param *
358 body_parameter,
359 struct mailmime_content ** result)
360{
361 struct mailmime_content * content;
362 struct mailmime_type * mime_type;
363 struct mailmime_discrete_type * discrete_type;
364 struct mailmime_composite_type * composite_type;
365 char * discrete_type_extension;
366 int discrete_type_type;
367 int composite_type_type;
368 int mime_type_type;
369 char * subtype;
370 int r;
371 int res;
372
373 discrete_type = NULL;
374 composite_type = NULL;
375 discrete_type_extension = NULL;
376 subtype = NULL;
377 discrete_type_type = 0;
378 composite_type_type = 0;
379 mime_type_type = 0;
380
381 switch (media_basic->med_type) {
382 case MAILIMAP_MEDIA_BASIC_APPLICATION:
383 mime_type_type = MAILMIME_TYPE_DISCRETE_TYPE;
384 discrete_type_type = MAILMIME_DISCRETE_TYPE_APPLICATION;
385 break;
386
387 case MAILIMAP_MEDIA_BASIC_AUDIO:
388 mime_type_type = MAILMIME_TYPE_DISCRETE_TYPE;
389 discrete_type_type = MAILMIME_DISCRETE_TYPE_APPLICATION;
390 break;
391
392 case MAILIMAP_MEDIA_BASIC_IMAGE:
393 mime_type_type = MAILMIME_TYPE_DISCRETE_TYPE;
394 discrete_type_type = MAILMIME_DISCRETE_TYPE_IMAGE;
395 break;
396
397 case MAILIMAP_MEDIA_BASIC_MESSAGE:
398 mime_type_type = MAILMIME_TYPE_COMPOSITE_TYPE;
399 composite_type_type = MAILMIME_COMPOSITE_TYPE_MESSAGE;
400 break;
401
402 case MAILIMAP_MEDIA_BASIC_VIDEO:
403 mime_type_type = MAILMIME_TYPE_DISCRETE_TYPE;
404 discrete_type_type = MAILMIME_DISCRETE_TYPE_VIDEO;
405 break;
406
407 case MAILIMAP_MEDIA_BASIC_OTHER:
408 mime_type_type = MAILMIME_TYPE_DISCRETE_TYPE;
409 discrete_type_type = MAILMIME_DISCRETE_TYPE_EXTENSION;
410 discrete_type_extension = media_basic->med_basic_type;
411 if (discrete_type_extension == NULL) {
412 res = MAIL_ERROR_INVAL;
413 goto err;
414 }
415
416 break;
417
418 default:
419 res = MAIL_ERROR_INVAL;
420 goto err;
421 }
422
423 switch (mime_type_type) {
424 case MAILMIME_TYPE_DISCRETE_TYPE:
425 if (discrete_type_extension != NULL) {
426 discrete_type_extension = strdup(discrete_type_extension);
427 if (discrete_type_extension == NULL) {
428 res = MAIL_ERROR_MEMORY;
429 goto err;
430 }
431 }
432
433 discrete_type = mailmime_discrete_type_new(discrete_type_type,
434 discrete_type_extension);
435 if (discrete_type == NULL) {
436 if (discrete_type_extension != NULL)
437 free(discrete_type_extension);
438 res = MAIL_ERROR_MEMORY;
439 goto err;
440 }
441
442 break;
443
444 case MAILMIME_TYPE_COMPOSITE_TYPE:
445 composite_type = mailmime_composite_type_new(composite_type_type,
446 NULL);
447 if (composite_type == NULL) {
448 res = MAIL_ERROR_MEMORY;
449 goto err;
450 }
451
452 break;
453
454 default:
455 res = MAIL_ERROR_INVAL;
456 goto err;
457 }
458
459 mime_type = mailmime_type_new(mime_type_type, discrete_type, composite_type);
460 if (mime_type == NULL) {
461 res = MAIL_ERROR_MEMORY;
462 goto free;
463 }
464
465 r = imap_body_parameter_to_content(body_parameter, media_basic->med_subtype,
466 mime_type, &content);
467 if (r != MAIL_NO_ERROR) {
468 res = r;
469 goto free_type;
470 }
471
472 * result = content;
473
474 return MAIL_NO_ERROR;
475
476 free_type:
477 mailmime_type_free(mime_type);
478 free:
479 if (discrete_type != NULL)
480 mailmime_discrete_type_free(discrete_type);
481 if (composite_type != NULL)
482 mailmime_composite_type_free(composite_type);
483 err:
484 return res;
485}
486
487static int
488imap_disposition_to_mime_disposition(struct mailimap_body_fld_dsp * imap_dsp,
489 struct mailmime_disposition ** result)
490{
491 size_t cur_token;
492 int r;
493 struct mailmime_disposition_type * dsp_type;
494 struct mailmime_disposition * dsp;
495 clist * parameters;
496 int res;
497
498 cur_token = 0;
499 r = mailmime_disposition_type_parse(imap_dsp->dsp_type,
500 strlen(imap_dsp->dsp_type), &cur_token, &dsp_type);
501 if (r != MAILIMF_NO_ERROR) {
502 res = MAILIMF_ERROR_PARSE;
503 goto err;
504 }
505
506 parameters = clist_new();
507 if (parameters == NULL) {
508 res = MAIL_ERROR_MEMORY;
509 goto err;
510 }
511
512 if (imap_dsp->dsp_attributes != NULL) {
513 clistiter * cur;
514
515 for(cur = clist_begin(imap_dsp->dsp_attributes->pa_list) ; cur != NULL ;
516 cur = clist_next(cur)) {
517 struct mailimap_single_body_fld_param * imap_param;
518 struct mailmime_disposition_parm * dsp_param;
519 struct mailmime_parameter * param;
520 char * filename;
521 char * creation_date;
522 char * modification_date;
523 char * read_date;
524 size_t size;
525 int type;
526
527 imap_param = clist_content(cur);
528
529 filename = NULL;
530 creation_date = NULL;
531 modification_date = NULL;
532 read_date = NULL;
533 size = 0;
534 param = NULL;
535
536 type = mailmime_disposition_guess_type(imap_param->pa_name,
537 strlen(imap_param->pa_name), 0);
538
539 switch (type) {
540 case MAILMIME_DISPOSITION_PARM_FILENAME:
541 if (strcasecmp(imap_param->pa_name, "filename") != 0) {
542 type = MAILMIME_DISPOSITION_PARM_PARAMETER;
543 break;
544 }
545 filename = strdup(imap_param->pa_value);
546 if (filename == NULL) {
547 res = MAIL_ERROR_MEMORY;
548 goto free_dsp_type;
549 }
550 break;
551
552 case MAILMIME_DISPOSITION_PARM_CREATION_DATE:
553 if (strcasecmp(imap_param->pa_name, "creation-date") != 0) {
554 type = MAILMIME_DISPOSITION_PARM_PARAMETER;
555 break;
556 }
557 creation_date = strdup(imap_param->pa_value);
558 if (creation_date == NULL) {
559 res = MAIL_ERROR_MEMORY;
560 goto free_dsp_type;
561 }
562 break;
563
564 case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE:
565 if (strcasecmp(imap_param->pa_name, "modification-date") != 0) {
566 type = MAILMIME_DISPOSITION_PARM_PARAMETER;
567 break;
568 }
569 modification_date = strdup(imap_param->pa_value);
570 if (modification_date == NULL) {
571 res = MAIL_ERROR_MEMORY;
572 goto free_dsp_type;
573 }
574 break;
575
576 case MAILMIME_DISPOSITION_PARM_READ_DATE:
577 if (strcasecmp(imap_param->pa_name, "read-date") != 0) {
578 type = MAILMIME_DISPOSITION_PARM_PARAMETER;
579 break;
580 }
581 read_date = strdup(imap_param->pa_value);
582 if (read_date == NULL) {
583 res = MAIL_ERROR_MEMORY;
584 goto free_dsp_type;
585 }
586 break;
587
588 case MAILMIME_DISPOSITION_PARM_SIZE:
589 if (strcasecmp(imap_param->pa_name, "size") != 0) {
590 type = MAILMIME_DISPOSITION_PARM_PARAMETER;
591 break;
592 }
593 size = strtoul(imap_param->pa_value, NULL, 10);
594 break;
595 }
596
597 if (type == MAILMIME_DISPOSITION_PARM_PARAMETER) {
598 char * name;
599 char * value;
600
601 name = strdup(imap_param->pa_name);
602 if (name == NULL) {
603 res = MAIL_ERROR_MEMORY;
604 goto free_dsp_type;
605 }
606
607 value = strdup(imap_param->pa_value);
608 if (value == NULL) {
609 res = MAIL_ERROR_MEMORY;
610 free(name);
611 goto free_dsp_type;
612 }
613
614 param = mailmime_parameter_new(name, value);
615 if (param == NULL) {
616 free(value);
617 free(name);
618 res = MAIL_ERROR_MEMORY;
619 goto free_dsp_type;
620 }
621
622 }
623
624 dsp_param = mailmime_disposition_parm_new(type, filename,
625 creation_date,
626 modification_date,
627 read_date,
628 size, param);
629 if (dsp_param == NULL) {
630 if (filename != NULL)
631 free(filename);
632 if (creation_date != NULL)
633 free(creation_date);
634 if (modification_date != NULL)
635 free(modification_date);
636 if (read_date != NULL)
637 free(read_date);
638 if (param != NULL)
639 mailmime_parameter_free(param);
640 res = MAIL_ERROR_MEMORY;
641 goto free_list;
642 }
643
644 r = clist_append(parameters, dsp_param);
645 if (r != 0) {
646 mailmime_disposition_parm_free(dsp_param);
647 res = MAIL_ERROR_MEMORY;
648 goto free_list;
649 }
650 }
651 }
652
653 dsp = mailmime_disposition_new(dsp_type, parameters);
654 if (dsp == NULL) {
655 res = MAIL_ERROR_MEMORY;
656 goto free_list;
657 }
658
659 * result = dsp;
660
661 return MAIL_NO_ERROR;
662
663 free_list:
664 clist_foreach(parameters,
665 (clist_func) mailmime_disposition_parm_free, NULL);
666 clist_free(parameters);
667 free_dsp_type:
668 mailmime_disposition_type_free(dsp_type);
669 err:
670 return res;
671}
672
673static int
674imap_language_to_mime_language(struct mailimap_body_fld_lang * imap_lang,
675 struct mailmime_language ** result)
676{
677 clist * list;
678 clistiter * cur;
679 int res;
680 char * single;
681 int r;
682 struct mailmime_language * lang;
683
684 list = clist_new();
685 if (list == NULL) {
686 res = MAIL_ERROR_MEMORY;
687 goto err;
688 }
689
690 switch (imap_lang->lg_type) {
691 case MAILIMAP_BODY_FLD_LANG_SINGLE:
692 if (imap_lang->lg_data.lg_single != NULL) {
693 single = strdup(imap_lang->lg_data.lg_single);
694 if (single == NULL) {
695 res = MAIL_ERROR_MEMORY;
696 goto free;
697 }
698 r = clist_append(list, single);
699 if (r < 0) {
700 free(single);
701 res = MAIL_ERROR_MEMORY;
702 goto free;
703 }
704 }
705
706 break;
707
708 case MAILIMAP_BODY_FLD_LANG_LIST:
709 for(cur = clist_begin(imap_lang->lg_data.lg_list) ;
710 cur != NULL ; cur = clist_next(cur)) {
711 single = strdup(clist_content(cur));
712 if (single == NULL) {
713 res = MAIL_ERROR_MEMORY;
714 goto free;
715 }
716 r = clist_append(list, single);
717 if (r < 0) {
718 free(single);
719 res = MAIL_ERROR_MEMORY;
720 goto free;
721 }
722 }
723 }
724
725 lang = mailmime_language_new(list);
726 if (lang == NULL) {
727 res = MAIL_ERROR_MEMORY;
728 goto free;
729 }
730
731 * result = lang;
732
733 return MAIL_NO_ERROR;
734
735 free:
736 clist_foreach(list, (clist_func) free, NULL);
737 clist_free(list);
738 err:
739 return res;
740}
741
742static int
743imap_body_fields_to_mime_fields(struct mailimap_body_fields * body_fields,
744 struct mailimap_body_fld_dsp * imap_dsp,
745 struct mailimap_body_fld_lang * imap_lang,
746 struct mailmime_fields ** result,
747 uint32_t * pbody_size)
748{
749 struct mailmime_field * mime_field;
750 struct mailmime_fields * mime_fields;
751 clist * list;
752 char * id;
753 struct mailmime_mechanism * encoding;
754 char * description;
755 struct mailmime_disposition * dsp;
756 struct mailmime_language * lang;
757 int type;
758 int r;
759 int res;
760
761 list = clist_new();
762 if (list == NULL) {
763 res = MAIL_ERROR_MEMORY;
764 goto err;
765 }
766
767 if (body_fields != NULL) {
768
769 if (pbody_size != NULL)
770 * pbody_size = body_fields->bd_size;
771
772 if (body_fields->bd_id != NULL) {
773 type = MAILMIME_FIELD_ID;
774 id = strdup(body_fields->bd_id);
775 if (id == NULL) {
776 res = MAIL_ERROR_MEMORY;
777 goto free_list;
778 }
779
780 mime_field = mailmime_field_new(type, NULL,
781 NULL, id, NULL, 0, NULL, NULL);
782 if (mime_field == NULL) {
783 free(id);
784 res = MAIL_ERROR_MEMORY;
785 goto free_list;
786 }
787
788 r = clist_append(list, mime_field);
789 if (r != 0) {
790 mailmime_field_free(mime_field);
791 res = MAIL_ERROR_MEMORY;
792 goto free_list;
793 }
794 }
795
796 if (body_fields->bd_description != NULL) {
797 type = MAILMIME_FIELD_DESCRIPTION;
798 description = strdup(body_fields->bd_description);
799 if (description == NULL) {
800 res = MAIL_ERROR_MEMORY;
801 goto free_list;
802 }
803
804 mime_field = mailmime_field_new(type, NULL,
805 NULL, NULL, description, 0, NULL, NULL);
806 if (mime_field == NULL) {
807 free(description);
808 res = MAIL_ERROR_MEMORY;
809 goto free_list;
810 }
811
812 r = clist_append(list, mime_field);
813 if (r != 0) {
814 mailmime_field_free(mime_field);
815 res = MAIL_ERROR_MEMORY;
816 goto free_list;
817 }
818 }
819
820 if (body_fields->bd_encoding != NULL) {
821 char * encoding_value;
822 int encoding_type;
823
824 type = MAILMIME_FIELD_TRANSFER_ENCODING;
825
826 encoding_value = NULL;
827 switch (body_fields->bd_encoding->enc_type) {
828 case MAILIMAP_BODY_FLD_ENC_7BIT:
829 encoding_type = MAILMIME_MECHANISM_7BIT;
830 break;
831 case MAILIMAP_BODY_FLD_ENC_8BIT:
832 encoding_type = MAILMIME_MECHANISM_8BIT;
833 break;
834 case MAILIMAP_BODY_FLD_ENC_BINARY:
835 encoding_type = MAILMIME_MECHANISM_BINARY;
836 break;
837 case MAILIMAP_BODY_FLD_ENC_BASE64:
838 encoding_type = MAILMIME_MECHANISM_BASE64;
839 break;
840 case MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE:
841 encoding_type = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
842 break;
843 case MAILIMAP_BODY_FLD_ENC_OTHER:
844 encoding_type = MAILMIME_MECHANISM_TOKEN;
845 encoding_value = strdup(body_fields->bd_encoding->enc_value);
846 if (encoding_value == NULL) {
847 res = MAIL_ERROR_MEMORY;
848 goto free_list;
849 }
850 break;
851 default:
852 res = MAIL_ERROR_INVAL;
853 goto free_list;
854 }
855
856 encoding = mailmime_mechanism_new(encoding_type, encoding_value);
857 if (encoding == NULL) {
858 if (encoding_value != NULL)
859 free(encoding_value);
860 res = MAIL_ERROR_MEMORY;
861 goto free_list;
862 }
863
864 mime_field = mailmime_field_new(type, NULL,
865 encoding, NULL, NULL, 0, NULL, NULL);
866 if (mime_field == NULL) {
867 mailmime_mechanism_free(encoding);
868 res = MAIL_ERROR_MEMORY;
869 goto free_list;
870 }
871
872 r = clist_append(list, mime_field);
873 if (r != 0) {
874 mailmime_field_free(mime_field);
875 res = MAIL_ERROR_MEMORY;
876 goto free_list;
877 }
878 }
879 }
880
881 if (imap_dsp != NULL) {
882 r = imap_disposition_to_mime_disposition(imap_dsp, &dsp);
883 if (r != MAIL_ERROR_PARSE) {
884 if (r != MAIL_NO_ERROR) {
885 res = MAIL_ERROR_MEMORY;
886 goto free_list;
887 }
888
889 type = MAILMIME_FIELD_DISPOSITION;
890
891 mime_field = mailmime_field_new(type, NULL,
892 NULL, NULL, NULL, 0, dsp, NULL);
893 if (mime_field == NULL) {
894 mailmime_disposition_free(dsp);
895 res = MAIL_ERROR_MEMORY;
896 goto free_list;
897 }
898
899 r = clist_append(list, mime_field);
900 if (r != 0) {
901 mailmime_field_free(mime_field);
902 res = MAIL_ERROR_MEMORY;
903 goto free_list;
904 }
905 }
906 }
907
908 if (imap_lang != NULL) {
909 r = imap_language_to_mime_language(imap_lang, &lang);
910 if (r != MAIL_NO_ERROR) {
911 res = MAIL_ERROR_MEMORY;
912 goto free_list;
913 }
914
915 type = MAILMIME_FIELD_LANGUAGE;
916
917 mime_field = mailmime_field_new(type, NULL,
918 NULL, NULL, NULL, 0, NULL, lang);
919 if (mime_field == NULL) {
920 mailmime_language_free(lang);
921 res = MAIL_ERROR_MEMORY;
922 goto free_list;
923 }
924
925 r = clist_append(list, mime_field);
926 if (r != 0) {
927 mailmime_field_free(mime_field);
928 res = MAIL_ERROR_MEMORY;
929 goto free_list;
930 }
931 }
932
933 mime_fields = mailmime_fields_new(list);
934 if (mime_fields == NULL) {
935 res = MAIL_ERROR_MEMORY;
936 goto free_list;
937 }
938
939 * result = mime_fields;
940
941 return MAIL_NO_ERROR;
942
943 free_list:
944 clist_foreach(list, (clist_func) mailmime_fields_free, NULL);
945 clist_free(list);
946 err:
947 return res;
948}
949
950static int
951imap_body_type_basic_to_body(struct mailimap_body_type_basic *
952 imap_type_basic,
953 struct mailimap_body_ext_1part *
954 body_ext_1part,
955 struct mailmime ** result)
956{
957 struct mailmime_content * content;
958 struct mailmime_fields * mime_fields;
959 struct mailmime * body;
960 int r;
961 int res;
962 uint32_t mime_size;
963
964 r = imap_body_media_basic_to_content_type(imap_type_basic->bd_media_basic,
965 imap_type_basic->bd_fields->bd_parameter, &content);
966 if (r != MAIL_NO_ERROR) {
967 res = r;
968 goto err;
969 }
970
971 if (body_ext_1part != NULL)
972 r = imap_body_fields_to_mime_fields(imap_type_basic->bd_fields,
973 body_ext_1part->bd_disposition,
974 body_ext_1part->bd_language,
975 &mime_fields, &mime_size);
976 else
977 r = imap_body_fields_to_mime_fields(imap_type_basic->bd_fields,
978 NULL, NULL,
979 &mime_fields, &mime_size);
980 if (r != MAIL_NO_ERROR) {
981 res = r;
982 goto free_content;
983 }
984
985 body = mailmime_new(MAILMIME_SINGLE, NULL,
986 mime_size, mime_fields, content,
987 NULL, NULL, NULL, NULL, NULL, NULL);
988
989 if (body == NULL) {
990 res = MAIL_ERROR_MEMORY;
991 goto free_fields;
992 }
993
994 * result = body;
995
996 return MAIL_NO_ERROR;
997
998 free_fields:
999 mailmime_fields_free(mime_fields);
1000 free_content:
1001 mailmime_content_free(content);
1002 err:
1003 return res;
1004}
1005
1006static int
1007imap_body_type_text_to_body(struct mailimap_body_type_text *
1008 imap_type_text,
1009 struct mailimap_body_ext_1part *
1010 body_ext_1part,
1011 struct mailmime ** result)
1012{
1013 struct mailmime_content * content;
1014 struct mailmime_fields * mime_fields;
1015 struct mailmime * body;
1016 int r;
1017 int res;
1018 uint32_t mime_size;
1019
1020 r = imap_body_type_text_to_content_type(imap_type_text->bd_media_text,
1021 imap_type_text->bd_fields->bd_parameter,
1022 &content);
1023 if (r != MAIL_NO_ERROR) {
1024 res = r;
1025 goto err;
1026 }
1027
1028 if (body_ext_1part == NULL) {
1029 r = imap_body_fields_to_mime_fields(imap_type_text->bd_fields,
1030 NULL, NULL,
1031 &mime_fields, &mime_size);
1032 }
1033 else {
1034 r = imap_body_fields_to_mime_fields(imap_type_text->bd_fields,
1035 body_ext_1part->bd_disposition,
1036 body_ext_1part->bd_language,
1037 &mime_fields, &mime_size);
1038 }
1039 if (r != MAIL_NO_ERROR) {
1040 res = r;
1041 goto free_content;
1042 }
1043
1044 body = mailmime_new(MAILMIME_SINGLE, NULL,
1045 mime_size, mime_fields, content,
1046 NULL, NULL, NULL, NULL, NULL, NULL);
1047
1048 if (body == NULL) {
1049 res = MAIL_ERROR_MEMORY;
1050 goto free_fields;
1051 }
1052
1053 * result = body;
1054
1055 return MAIL_NO_ERROR;
1056
1057 free_fields:
1058 mailmime_fields_free(mime_fields);
1059 free_content:
1060 mailmime_content_free(content);
1061 err:
1062 return res;
1063}
1064
1065static int
1066imap_body_parameter_to_content(struct mailimap_body_fld_param *
1067 body_parameter,
1068 char * subtype,
1069 struct mailmime_type * mime_type,
1070 struct mailmime_content ** result)
1071{
1072 clist * parameters;
1073 char * new_subtype;
1074 struct mailmime_content * content;
1075 int r;
1076 int res;
1077
1078 new_subtype = strdup(subtype);
1079 if (new_subtype == NULL) {
1080 res = MAIL_ERROR_MEMORY;
1081 goto err;
1082 }
1083
1084 parameters = clist_new();
1085 if (parameters == NULL) {
1086 res = MAIL_ERROR_MEMORY;
1087 goto free_subtype;
1088 }
1089
1090 if (body_parameter != NULL) {
1091 clistiter * cur;
1092
1093 for(cur = clist_begin(body_parameter->pa_list) ; cur != NULL ;
1094 cur = clist_next(cur)) {
1095 struct mailimap_single_body_fld_param * imap_param;
1096 struct mailmime_parameter * param;
1097 char * name;
1098 char * value;
1099
1100 imap_param = clist_content(cur);
1101 name = strdup(imap_param->pa_name);
1102 if (name == NULL) {
1103 res = MAIL_ERROR_MEMORY;
1104 goto free_parameters;
1105 }
1106
1107 value = strdup(imap_param->pa_value);
1108 if (value == NULL) {
1109 free(name);
1110 res = MAIL_ERROR_MEMORY;
1111 goto free_parameters;
1112 }
1113
1114 param = mailmime_parameter_new(name, value);
1115 if (param == NULL) {
1116 free(value);
1117 free(name);
1118 res = MAIL_ERROR_MEMORY;
1119 goto free_parameters;
1120 }
1121
1122 r = clist_append(parameters, param);
1123 if (r != 0) {
1124 mailmime_parameter_free(param);
1125 res = MAIL_ERROR_MEMORY;
1126 goto free_parameters;
1127 }
1128 }
1129 }
1130
1131 content = mailmime_content_new(mime_type, new_subtype, parameters);
1132 if (content == NULL) {
1133 res = MAIL_ERROR_MEMORY;
1134 goto free_parameters;
1135 }
1136
1137 * result = content;
1138
1139 return MAIL_NO_ERROR;
1140
1141 free_parameters:
1142 clist_foreach(parameters, (clist_func) mailmime_parameter_free, NULL);
1143 clist_free(parameters);
1144 free_subtype:
1145 free(new_subtype);
1146 err:
1147 return res;
1148}
1149
1150static int
1151imap_body_type_text_to_content_type(char * subtype,
1152 struct mailimap_body_fld_param *
1153 body_parameter,
1154 struct mailmime_content ** result)
1155{
1156 struct mailmime_content * content;
1157 struct mailmime_type * mime_type;
1158 struct mailmime_discrete_type * discrete_type;
1159 int r;
1160 int res;
1161
1162 discrete_type = NULL;
1163
1164 discrete_type = mailmime_discrete_type_new(MAILMIME_DISCRETE_TYPE_TEXT,
1165 NULL);
1166 if (discrete_type == NULL) {
1167 res = MAIL_ERROR_MEMORY;
1168 goto err;
1169 }
1170
1171 mime_type = mailmime_type_new(MAILMIME_TYPE_DISCRETE_TYPE,
1172 discrete_type, NULL);
1173 if (mime_type == NULL) {
1174 mailmime_discrete_type_free(discrete_type);
1175 res = MAIL_ERROR_MEMORY;
1176 goto err;
1177 }
1178
1179 r = imap_body_parameter_to_content(body_parameter, subtype,
1180 mime_type, &content);
1181 if (r != MAIL_NO_ERROR) {
1182 res = r;
1183 goto free_type;
1184 }
1185
1186 * result = content;
1187
1188 return MAIL_NO_ERROR;
1189
1190 free_type:
1191 mailmime_type_free(mime_type);
1192 err:
1193 return res;
1194}
1195
1196
1197static int
1198imap_body_type_msg_to_body(struct mailimap_body_type_msg *
1199 imap_type_msg,
1200 struct mailimap_body_ext_1part *
1201 body_ext_1part,
1202 struct mailmime ** result)
1203{
1204 struct mailmime * body;
1205 struct mailmime * msg_body;
1206 struct mailmime_fields * mime_fields;
1207 struct mailmime_composite_type * composite_type;
1208 struct mailmime_type * mime_type;
1209 struct mailmime_content * content_type;
1210 struct mailimf_fields * fields;
1211 int r;
1212 int res;
1213 uint32_t mime_size;
1214
1215 r = imap_body_fields_to_mime_fields(imap_type_msg->bd_fields,
1216 body_ext_1part->bd_disposition, body_ext_1part->bd_language,
1217 &mime_fields, &mime_size);
1218 if (r != MAIL_NO_ERROR) {
1219 res = r;
1220 goto err;
1221 }
1222
1223 r = imap_env_to_fields(imap_type_msg->bd_envelope, NULL, 0, &fields);
1224 if (r != MAIL_NO_ERROR) {
1225 res = r;
1226 goto free_mime_fields;
1227 }
1228
1229 r = imap_body_to_body(imap_type_msg->bd_body, &msg_body);
1230 if (r != MAIL_NO_ERROR) {
1231 res = r;
1232 goto free_fields;
1233 }
1234
1235 composite_type =
1236 mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MESSAGE,
1237 NULL);
1238 if (composite_type == NULL) {
1239 res = MAIL_ERROR_MEMORY;
1240 goto free_fields;
1241 }
1242
1243 mime_type = mailmime_type_new(MAILMIME_TYPE_COMPOSITE_TYPE,
1244 NULL, composite_type);
1245 if (mime_type == NULL) {
1246 mailmime_composite_type_free(composite_type);
1247 res = MAIL_ERROR_MEMORY;
1248 goto free_fields;
1249 }
1250
1251 r = imap_body_parameter_to_content(imap_type_msg->bd_fields->bd_parameter,
1252 "rfc822", mime_type, &content_type);
1253 if (r != MAIL_NO_ERROR) {
1254 mailmime_type_free(mime_type);
1255 res = MAIL_ERROR_MEMORY;
1256 goto free_fields;
1257 }
1258
1259 body = mailmime_new(MAILMIME_MESSAGE, NULL,
1260 mime_size, mime_fields, content_type,
1261 NULL, NULL, NULL, NULL, fields, msg_body);
1262
1263 if (body == NULL) {
1264 res = MAIL_ERROR_MEMORY;
1265 goto free_content;
1266 }
1267
1268 * result = body;
1269
1270 return MAIL_NO_ERROR;
1271
1272 free_content:
1273 mailmime_content_free(content_type);
1274 free_fields:
1275 mailimf_fields_free(fields);
1276 free_mime_fields:
1277 mailmime_fields_free(mime_fields);
1278 err:
1279 return res;
1280}
1281
1282
1283static int
1284imap_body_type_1part_to_body(struct mailimap_body_type_1part *
1285 type_1part,
1286 struct mailmime ** result)
1287{
1288 struct mailmime * body;
1289 int r;
1290 int res;
1291
1292 switch (type_1part->bd_type) {
1293 case MAILIMAP_BODY_TYPE_1PART_BASIC:
1294 r = imap_body_type_basic_to_body(type_1part->bd_data.bd_type_basic,
1295 type_1part->bd_ext_1part,
1296 &body);
1297 if (r != MAIL_NO_ERROR) {
1298 res = r;
1299 goto err;
1300 }
1301
1302 break;
1303 case MAILIMAP_BODY_TYPE_1PART_MSG:
1304 r = imap_body_type_msg_to_body(type_1part->bd_data.bd_type_msg,
1305 type_1part->bd_ext_1part,
1306 &body);
1307 if (r != MAIL_NO_ERROR) {
1308 res = r;
1309 goto err;
1310 }
1311
1312 break;
1313 case MAILIMAP_BODY_TYPE_1PART_TEXT:
1314 r = imap_body_type_text_to_body(type_1part->bd_data.bd_type_text,
1315 type_1part->bd_ext_1part,
1316 &body);
1317 if (r != MAIL_NO_ERROR) {
1318 res = r;
1319 goto err;
1320 }
1321
1322 break;
1323 }
1324
1325 * result = body;
1326
1327 return MAIL_NO_ERROR;
1328
1329 err:
1330 return res;
1331}
1332
1333static int
1334imap_body_type_mpart_to_body(struct mailimap_body_type_mpart *
1335 type_mpart,
1336 struct mailmime ** result)
1337{
1338 struct mailmime_fields * mime_fields;
1339 struct mailmime_composite_type * composite_type;
1340 struct mailmime_type * mime_type;
1341 struct mailmime_content * content_type;
1342 struct mailmime * body;
1343 clistiter * cur;
1344 clist * list;
1345 int r;
1346 int res;
1347 uint32_t mime_size;
1348
1349 r = imap_body_fields_to_mime_fields(NULL,
1350 type_mpart->bd_ext_mpart->bd_disposition,
1351 type_mpart->bd_ext_mpart->bd_language,
1352 &mime_fields, &mime_size);
1353 if (r != MAIL_NO_ERROR) {
1354 res = r;
1355 goto err;
1356 }
1357
1358 composite_type =
1359 mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MULTIPART,
1360 NULL);
1361 if (composite_type == NULL) {
1362 res = MAIL_ERROR_MEMORY;
1363 goto free_fields;
1364 }
1365
1366 mime_type = mailmime_type_new(MAILMIME_TYPE_COMPOSITE_TYPE,
1367 NULL, composite_type);
1368 if (mime_type == NULL) {
1369 mailmime_composite_type_free(composite_type);
1370 res = MAIL_ERROR_MEMORY;
1371 goto free_fields;
1372 }
1373
1374 r = imap_body_parameter_to_content(type_mpart->bd_ext_mpart->bd_parameter,
1375 type_mpart->bd_media_subtype,
1376 mime_type, &content_type);
1377 if (r != MAIL_NO_ERROR) {
1378 mailmime_type_free(mime_type);
1379 res = r;
1380 goto free_fields;
1381 }
1382
1383 list = clist_new();
1384 if (list == NULL) {
1385 res = MAIL_ERROR_MEMORY;
1386 goto free_content;
1387 }
1388
1389 for(cur = clist_begin(type_mpart->bd_list) ; cur != NULL ;
1390 cur = clist_next(cur)) {
1391 struct mailimap_body * imap_body;
1392 struct mailmime * sub_body;
1393
1394 imap_body = clist_content(cur);
1395
1396 r = imap_body_to_body(imap_body, &sub_body);
1397 if (r != MAIL_NO_ERROR) {
1398 res = r;
1399 goto free_list;
1400 }
1401
1402 r = clist_append(list, sub_body);
1403 if (r != 0) {
1404 mailmime_free(sub_body);
1405 res = r;
1406 goto free_list;
1407 }
1408 }
1409
1410 body = mailmime_new(MAILMIME_MULTIPLE, NULL,
1411 mime_size, mime_fields, content_type,
1412 NULL, NULL, NULL, list, NULL, NULL);
1413
1414 if (body == NULL) {
1415 res = MAIL_ERROR_MEMORY;
1416 goto err;
1417 }
1418
1419 * result = body;
1420
1421 return MAIL_NO_ERROR;
1422
1423 free_list:
1424 clist_foreach(list, (clist_func) mailmime_free, NULL);
1425 clist_free(list);
1426 free_content:
1427 mailmime_content_free(content_type);
1428 free_fields:
1429 mailmime_fields_free(mime_fields);
1430 err:
1431 return res;
1432}
1433
1434
1435int imap_body_to_body(struct mailimap_body * imap_body,
1436 struct mailmime ** result)
1437{
1438 struct mailmime * body;
1439 int r;
1440 int res;
1441
1442 switch (imap_body->bd_type) {
1443 case MAILIMAP_BODY_1PART:
1444 r = imap_body_type_1part_to_body(imap_body->bd_data.bd_body_1part, &body);
1445 if (r != MAIL_NO_ERROR) {
1446 res = r;
1447 goto err;
1448 }
1449 break;
1450 case MAILIMAP_BODY_MPART:
1451 r = imap_body_type_mpart_to_body(imap_body->bd_data.bd_body_mpart, &body);
1452 if (r != MAIL_NO_ERROR) {
1453 res = r;
1454 goto err;
1455 }
1456 break;
1457 default:
1458 return MAIL_ERROR_INVAL;
1459 }
1460
1461 * result = body;
1462
1463 return MAIL_NO_ERROR;
1464
1465 err:
1466 return res;
1467}
1468
1469int imap_address_to_mailbox(struct mailimap_address * imap_addr,
1470 struct mailimf_mailbox ** result)
1471{
1472 char * dsp_name;
1473 char * addr;
1474 struct mailimf_mailbox * mb;
1475 int res;
1476
1477 if (imap_addr->ad_personal_name == NULL)
1478 dsp_name = NULL;
1479 else {
1480 dsp_name = strdup(imap_addr->ad_personal_name);
1481 if (dsp_name == NULL) {
1482 res = MAIL_ERROR_MEMORY;
1483 goto err;
1484 }
1485 }
1486
1487 if (imap_addr->ad_host_name == NULL) {
1488 addr = strdup(imap_addr->ad_mailbox_name);
1489 if (addr == NULL) {
1490 res = MAIL_ERROR_MEMORY;
1491 goto free_name;
1492 }
1493 }
1494 else {
1495 addr = malloc(strlen(imap_addr->ad_mailbox_name) +
1496 strlen(imap_addr->ad_host_name) + 2);
1497 if (addr == NULL) {
1498 res = MAIL_ERROR_MEMORY;
1499 goto free_name;
1500 }
1501 strcpy(addr, imap_addr->ad_mailbox_name);
1502 strcat(addr, "@");
1503 strcat(addr, imap_addr->ad_host_name);
1504 }
1505
1506 mb = mailimf_mailbox_new(dsp_name, addr);
1507 if (mb == NULL) {
1508 res = MAIL_ERROR_MEMORY;
1509 goto free_addr;
1510 }
1511
1512 * result = mb;
1513
1514 return MAIL_NO_ERROR;
1515
1516 free_addr:
1517 free(addr);
1518 free_name:
1519 free(dsp_name);
1520 err:
1521 return res;
1522}
1523
1524int imap_address_to_address(struct mailimap_address * imap_addr,
1525 struct mailimf_address ** result)
1526{
1527 struct mailimf_address * addr;
1528 struct mailimf_mailbox * mb;
1529 int r;
1530 int res;
1531
1532 r = imap_address_to_mailbox(imap_addr, &mb);
1533 if (r != MAIL_NO_ERROR) {
1534 res = r;
1535 goto err;
1536 }
1537
1538 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
1539 if (addr == NULL) {
1540 res = MAIL_ERROR_MEMORY;
1541 goto free_mb;
1542 }
1543
1544 * result = addr;
1545
1546 return MAIL_NO_ERROR;
1547
1548 free_mb:
1549 mailimf_mailbox_free(mb);
1550 err:
1551 return res;
1552}
1553
1554int
1555imap_mailbox_list_to_mailbox_list(clist * imap_mailbox_list,
1556 struct mailimf_mailbox_list ** result)
1557{
1558 clistiter * cur;
1559 clist * list;
1560 struct mailimf_mailbox_list * mb_list;
1561 int r;
1562 int res;
1563
1564 list = clist_new();
1565 if (list == NULL) {
1566 res = MAIL_ERROR_MEMORY;
1567 goto err;
1568 }
1569
1570 for(cur = clist_begin(imap_mailbox_list) ; cur != NULL ;
1571 cur = clist_next(cur)) {
1572 struct mailimap_address * imap_addr;
1573 struct mailimf_mailbox * mb;
1574
1575 imap_addr = clist_content(cur);
1576
1577 if (imap_addr->ad_mailbox_name == NULL)
1578 continue;
1579
1580 r = imap_address_to_mailbox(imap_addr, &mb);
1581 if (r != MAIL_NO_ERROR) {
1582 res = r;
1583 goto free_list;
1584 }
1585
1586 r = clist_append(list, mb);
1587 if (r != 0) {
1588 mailimf_mailbox_free(mb);
1589 res = MAIL_ERROR_MEMORY;
1590 goto free_list;
1591 }
1592 }
1593
1594 mb_list = mailimf_mailbox_list_new(list);
1595 if (mb_list == NULL) {
1596 res = MAIL_ERROR_MEMORY;
1597 goto free_list;
1598 }
1599
1600 * result = mb_list;
1601
1602 return MAIL_NO_ERROR;
1603
1604 free_list:
1605 clist_foreach(list, (clist_func) mailimf_mailbox_free, NULL);
1606 clist_free(list);
1607 err:
1608 return MAIL_ERROR_MEMORY;
1609}
1610
1611
1612
1613/*
1614 at exit, imap_mb_list will fall on the last element of the group,
1615 where mailbox name will be NIL, so that imap_mailbox_list_to_address_list
1616 can continue
1617*/
1618
1619static int imap_mailbox_list_to_group(clist * imap_mb_list, clistiter ** iter,
1620 struct mailimf_group ** result)
1621{
1622 clistiter * imap_mailbox_listiter;
1623 clist * list;
1624 struct mailimf_group * group;
1625 struct mailimap_address * imap_addr;
1626 char * group_name;
1627 clistiter * cur;
1628 struct mailimf_mailbox_list * mb_list;
1629 int r;
1630 int res;
1631
1632 imap_mailbox_listiter = * iter;
1633
1634 imap_addr = clist_content(imap_mailbox_listiter);
1635 if (imap_addr->ad_mailbox_name == NULL) {
1636 res = MAIL_ERROR_INVAL;
1637 goto err;
1638 }
1639
1640 group_name = strdup(imap_addr->ad_mailbox_name);
1641 if (group_name == NULL) {
1642 res = MAIL_ERROR_MEMORY;
1643 goto err;
1644 }
1645
1646 list = clist_new();
1647 if (list == NULL) {
1648 res = MAIL_ERROR_MEMORY;
1649 goto free_group_name;
1650 }
1651
1652 for(cur = clist_next(imap_mailbox_listiter) ; cur != NULL ;
1653 cur = clist_next(cur)) {
1654 struct mailimf_mailbox * mb;
1655
1656 imap_addr = clist_content(cur);
1657
1658 if (imap_addr->ad_mailbox_name == NULL) {
1659 break;
1660 }
1661
1662 r = imap_address_to_mailbox(imap_addr, &mb);
1663 if (r != MAIL_NO_ERROR) {
1664 res = r;
1665 goto free_list;
1666 }
1667
1668 r = clist_append(list, mb);
1669 if (r != 0) {
1670 mailimf_mailbox_free(mb);
1671 res = MAIL_ERROR_MEMORY;
1672 goto free_list;
1673 }
1674 }
1675
1676 mb_list = mailimf_mailbox_list_new(list);
1677 if (mb_list == NULL) {
1678 res = MAIL_ERROR_MEMORY;
1679 goto free_list;
1680 }
1681
1682 group = mailimf_group_new(group_name, mb_list);
1683 if (group == NULL) {
1684 mailimf_mailbox_list_free(mb_list);
1685 res = MAIL_ERROR_MEMORY;
1686 goto free_group_name;
1687 }
1688
1689 * result = group;
1690 * iter = cur;
1691
1692 return MAIL_NO_ERROR;
1693
1694 free_list:
1695 clist_foreach(list, (clist_func) mailimf_mailbox_free, NULL);
1696 clist_free(list);
1697 free_group_name:
1698 free(group_name);
1699 err:
1700 return res;
1701}
1702
1703int
1704imap_mailbox_list_to_address_list(clist * imap_mailbox_list,
1705 struct mailimf_address_list ** result)
1706{
1707 clistiter * cur;
1708 clist * list;
1709 struct mailimf_address_list * addr_list;
1710 int r;
1711 int res;
1712
1713 list = clist_new();
1714 if (list == NULL) {
1715 res = MAIL_ERROR_MEMORY;
1716 goto err;
1717 }
1718
1719 for(cur = clist_begin(imap_mailbox_list) ; cur != NULL ;
1720 cur = clist_next(cur)) {
1721 struct mailimap_address * imap_addr;
1722 struct mailimf_address * addr;
1723
1724 imap_addr = clist_content(cur);
1725
1726 if (imap_addr->ad_mailbox_name == NULL)
1727 continue;
1728
1729 if ((imap_addr->ad_host_name == NULL) &&
1730 (imap_addr->ad_mailbox_name != NULL)) {
1731 struct mailimf_group * group;
1732
1733 r = imap_mailbox_list_to_group(imap_mailbox_list, &cur, &group);
1734 if (r != MAIL_NO_ERROR) {
1735 res = r;
1736 goto free_list;
1737 }
1738
1739 addr = mailimf_address_new(MAILIMF_ADDRESS_GROUP, NULL, group);
1740 if (addr == NULL) {
1741 mailimf_group_free(group);
1742 res = MAIL_ERROR_MEMORY;
1743 goto free_list;
1744 }
1745 }
1746 else {
1747 r = imap_address_to_address(imap_addr, &addr);
1748 if (r != MAIL_NO_ERROR) {
1749 res = r;
1750 goto free_list;
1751 }
1752 }
1753
1754 r = clist_append(list, addr);
1755 if (r != 0) {
1756 mailimf_address_free(addr);
1757 res = MAIL_ERROR_MEMORY;
1758 goto free_list;
1759 }
1760 }
1761
1762 addr_list = mailimf_address_list_new(list);
1763 if (addr_list == NULL) {
1764 res = MAIL_ERROR_MEMORY;
1765 goto free_list;
1766 }
1767
1768 * result = addr_list;
1769
1770 return MAIL_NO_ERROR;
1771
1772 free_list:
1773 clist_foreach(list, (clist_func) mailimf_address_free, NULL);
1774 clist_free(list);
1775 err:
1776 return res;
1777}
1778
1779
1780int imap_add_envelope_fetch_att(struct mailimap_fetch_type * fetch_type)
1781{
1782 struct mailimap_fetch_att * fetch_att;
1783 int res;
1784 int r;
1785 char * header;
1786 clist * hdrlist;
1787 struct mailimap_header_list * imap_hdrlist;
1788 struct mailimap_section * section;
1789
1790 fetch_att = mailimap_fetch_att_new_envelope();
1791 if (fetch_att == NULL) {
1792 res = MAIL_ERROR_MEMORY;
1793 goto err;
1794 }
1795
1796 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
1797 if (r != MAILIMAP_NO_ERROR) {
1798 mailimap_fetch_att_free(fetch_att);
1799 res = MAIL_ERROR_MEMORY;
1800 goto err;
1801 }
1802
1803 header = strdup("References");
1804 if (header == NULL) {
1805 mailimap_fetch_att_free(fetch_att);
1806 res = MAIL_ERROR_MEMORY;
1807 goto err;
1808 }
1809
1810 hdrlist = clist_new();
1811 if (hdrlist == NULL) {
1812 free(header);
1813 mailimap_fetch_att_free(fetch_att);
1814 res = MAIL_ERROR_MEMORY;
1815 goto err;
1816 }
1817
1818 r = clist_append(hdrlist, header);
1819 if (r < 0) {
1820 free(header);
1821 clist_foreach(hdrlist, (clist_func) free, NULL);
1822 clist_free(hdrlist);
1823 mailimap_fetch_att_free(fetch_att);
1824 res = MAIL_ERROR_MEMORY;
1825 goto err;
1826 }
1827
1828 imap_hdrlist = mailimap_header_list_new(hdrlist);
1829 if (imap_hdrlist == 0) {
1830 clist_foreach(hdrlist, (clist_func) free, NULL);
1831 clist_free(hdrlist);
1832 mailimap_fetch_att_free(fetch_att);
1833 res = MAIL_ERROR_MEMORY;
1834 goto err;
1835 }
1836
1837 section = mailimap_section_new_header_fields(imap_hdrlist);
1838 if (section == NULL) {
1839 mailimap_header_list_free(imap_hdrlist);
1840 mailimap_fetch_att_free(fetch_att);
1841 res = MAIL_ERROR_MEMORY;
1842 goto err;
1843 }
1844
1845 fetch_att = mailimap_fetch_att_new_body_peek_section(section);
1846 if (fetch_att == NULL) {
1847 mailimap_section_free(section);
1848 res = MAIL_ERROR_MEMORY;
1849 goto err;
1850 }
1851
1852 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
1853 if (r != MAILIMAP_NO_ERROR) {
1854 mailimap_fetch_att_free(fetch_att);
1855 res = MAIL_ERROR_MEMORY;
1856 goto err;
1857 }
1858
1859 return MAIL_NO_ERROR;
1860
1861 err:
1862 return res;
1863}
1864
1865
1866int imap_env_to_fields(struct mailimap_envelope * env,
1867 char * ref_str, size_t ref_size,
1868 struct mailimf_fields ** result)
1869{
1870 clist * list;
1871 struct mailimf_field * field;
1872 int r;
1873 struct mailimf_fields * fields;
1874 int res;
1875
1876 list = clist_new();
1877 if (list == NULL) {
1878 res = MAIL_ERROR_MEMORY;
1879 goto err;
1880 }
1881
1882 if (env->env_date != NULL) {
1883 size_t cur_token;
1884 struct mailimf_date_time * date_time;
1885
1886 cur_token = 0;
1887 r = mailimf_date_time_parse(env->env_date, strlen(env->env_date),
1888 &cur_token, &date_time);
1889
1890 if (r == MAILIMF_NO_ERROR) {
1891 struct mailimf_orig_date * orig;
1892
1893 orig = mailimf_orig_date_new(date_time);
1894 if (orig == NULL) {
1895 mailimf_date_time_free(date_time);
1896 res = MAIL_ERROR_MEMORY;
1897 goto free_list;
1898 }
1899
1900 field = mailimf_field_new(MAILIMF_FIELD_ORIG_DATE,
1901 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1902 NULL, orig, NULL,
1903 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1904 NULL, NULL, NULL, NULL, NULL);
1905 if (field == NULL) {
1906 mailimf_orig_date_free(orig);
1907 res = MAIL_ERROR_MEMORY;
1908 goto free_list;
1909 }
1910
1911 r = clist_append(list, field);
1912 if (r != 0) {
1913 mailimf_field_free(field);
1914 res = MAIL_ERROR_MEMORY;
1915 goto free_list;
1916 }
1917 }
1918 }
1919
1920 if (env->env_subject != NULL) {
1921 char * subject;
1922 struct mailimf_subject * subject_field;
1923
1924 subject = strdup(env->env_subject);
1925 if (subject == NULL) {
1926 res = MAIL_ERROR_MEMORY;
1927 goto free_list;
1928 }
1929
1930
1931 subject_field = mailimf_subject_new(subject);
1932 if (subject_field == NULL) {
1933 free(subject);
1934 res = MAIL_ERROR_MEMORY;
1935 goto free_list;
1936 }
1937
1938 field = mailimf_field_new(MAILIMF_FIELD_SUBJECT,
1939 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1940 NULL, NULL, NULL,
1941 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1942 NULL, subject_field, NULL, NULL, NULL);
1943 if (field == NULL) {
1944 mailimf_subject_free(subject_field);
1945 res = MAIL_ERROR_MEMORY;
1946 goto free_list;
1947 }
1948
1949 r = clist_append(list, field);
1950 if (r != 0) {
1951 mailimf_field_free(field);
1952 res = MAIL_ERROR_MEMORY;
1953 goto free_list;
1954 }
1955 }
1956
1957 if (env->env_from != NULL) {
1958 if (env->env_from->frm_list != NULL) {
1959 struct mailimf_mailbox_list * mb_list;
1960 struct mailimf_from * from;
1961
1962 r = imap_mailbox_list_to_mailbox_list(env->env_from->frm_list, &mb_list);
1963
1964 if (r != MAIL_NO_ERROR) {
1965 res = r;
1966 goto free_list;
1967 }
1968
1969 from = mailimf_from_new(mb_list);
1970 if (from == NULL) {
1971 mailimf_mailbox_list_free(mb_list);
1972 res = MAIL_ERROR_MEMORY;
1973 goto free_list;
1974 }
1975
1976 field = mailimf_field_new(MAILIMF_FIELD_FROM,
1977 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1978 NULL, NULL, from,
1979 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1980 NULL, NULL, NULL, NULL, NULL);
1981 if (field == NULL) {
1982 mailimf_from_free(from);
1983 res = MAIL_ERROR_MEMORY;
1984 goto free_list;
1985 }
1986
1987 r = clist_append(list, field);
1988 if (r != 0) {
1989 mailimf_field_free(field);
1990 res = MAIL_ERROR_MEMORY;
1991 goto free_list;
1992 }
1993 }
1994 }
1995
1996 if (env->env_sender != NULL) {
1997 if (env->env_sender->snd_list != NULL) {
1998 struct mailimf_sender * sender;
1999 struct mailimf_mailbox * mb;
2000
2001 r = imap_address_to_mailbox(clist_begin(env->env_sender->snd_list)->data, &mb);
2002
2003 if (r != MAIL_NO_ERROR) {
2004 res = r;
2005 goto free_list;
2006 }
2007
2008 sender = mailimf_sender_new(mb);
2009 if (sender == NULL) {
2010 mailimf_mailbox_free(mb);
2011 res = MAIL_ERROR_MEMORY;
2012 goto free_list;
2013 }
2014
2015 field = mailimf_field_new(MAILIMF_FIELD_SENDER,
2016 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2017 NULL, NULL, NULL,
2018 sender, NULL, NULL, NULL, NULL, NULL, NULL,
2019 NULL, NULL, NULL, NULL, NULL);
2020 if (field == NULL) {
2021 mailimf_sender_free(sender);
2022 res = MAIL_ERROR_MEMORY;
2023 goto free_list;
2024 }
2025
2026 r = clist_append(list, field);
2027 if (r != 0) {
2028 mailimf_field_free(field);
2029 res = MAIL_ERROR_MEMORY;
2030 goto free_list;
2031 }
2032 }
2033 }
2034
2035 if (env->env_reply_to != NULL) {
2036 if (env->env_reply_to->rt_list != NULL) {
2037 struct mailimf_address_list * addr_list;
2038 struct mailimf_reply_to * reply_to;
2039
2040 r = imap_mailbox_list_to_address_list(env->env_reply_to->rt_list,
2041 &addr_list);
2042
2043 if (r != MAIL_NO_ERROR) {
2044 res = r;
2045 goto free_list;
2046 }
2047
2048 reply_to = mailimf_reply_to_new(addr_list);
2049 if (reply_to == NULL) {
2050 mailimf_address_list_free(addr_list);
2051 res = MAIL_ERROR_MEMORY;
2052 goto free_list;
2053 }
2054
2055 field = mailimf_field_new(MAILIMF_FIELD_REPLY_TO,
2056 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2057 NULL, NULL, NULL,
2058 NULL, reply_to, NULL, NULL, NULL, NULL, NULL,
2059 NULL, NULL, NULL, NULL, NULL);
2060 if (field == NULL) {
2061 mailimf_reply_to_free(reply_to);
2062 res = MAIL_ERROR_MEMORY;
2063 goto free_list;
2064 }
2065
2066 r = clist_append(list, field);
2067 if (r != 0) {
2068 mailimf_field_free(field);
2069 res = MAIL_ERROR_MEMORY;
2070 goto free_list;
2071 }
2072 }
2073 }
2074
2075 if (env->env_to != NULL) {
2076 if (env->env_to->to_list != NULL) {
2077 struct mailimf_address_list * addr_list;
2078 struct mailimf_to * to;
2079
2080 r = imap_mailbox_list_to_address_list(env->env_to->to_list, &addr_list);
2081
2082 if (r != MAIL_NO_ERROR) {
2083 res = r;
2084 goto free_list;
2085 }
2086
2087 to = mailimf_to_new(addr_list);
2088 if (to == NULL) {
2089 mailimf_address_list_free(addr_list);
2090 res = MAIL_ERROR_MEMORY;
2091 goto free_list;
2092 }
2093
2094 field = mailimf_field_new(MAILIMF_FIELD_TO,
2095 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2096 NULL, NULL, NULL,
2097 NULL, NULL, to, NULL, NULL, NULL, NULL,
2098 NULL, NULL, NULL, NULL, NULL);
2099 if (field == NULL) {
2100 mailimf_to_free(to);
2101 res = MAIL_ERROR_MEMORY;
2102 goto free_list;
2103 }
2104
2105 r = clist_append(list, field);
2106 if (r != 0) {
2107 mailimf_field_free(field);
2108 res = MAIL_ERROR_MEMORY;
2109 goto free_list;
2110 }
2111 }
2112 }
2113
2114 if (env->env_cc != NULL) {
2115 if (env->env_cc->cc_list != NULL) {
2116 struct mailimf_address_list * addr_list;
2117 struct mailimf_cc * cc;
2118
2119 r = imap_mailbox_list_to_address_list(env->env_cc->cc_list, &addr_list);
2120
2121 if (r != MAIL_NO_ERROR) {
2122 res = r;
2123 goto free_list;
2124 }
2125
2126 cc = mailimf_cc_new(addr_list);
2127 if (cc == NULL) {
2128 mailimf_address_list_free(addr_list);
2129 res = MAIL_ERROR_MEMORY;
2130 goto free_list;
2131 }
2132
2133 field = mailimf_field_new(MAILIMF_FIELD_CC,
2134 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2135 NULL, NULL, NULL,
2136 NULL, NULL, NULL, cc, NULL, NULL, NULL,
2137 NULL, NULL, NULL, NULL, NULL);
2138 if (field == NULL) {
2139 mailimf_cc_free(cc);
2140 res = MAIL_ERROR_MEMORY;
2141 goto free_list;
2142 }
2143
2144 r = clist_append(list, field);
2145 if (r != 0) {
2146 mailimf_field_free(field);
2147 res = MAIL_ERROR_MEMORY;
2148 goto free_list;
2149 }
2150 }
2151 }
2152
2153 if (env->env_bcc != NULL) {
2154 if (env->env_bcc->bcc_list != NULL) {
2155 struct mailimf_address_list * addr_list;
2156 struct mailimf_bcc * bcc;
2157
2158 r = imap_mailbox_list_to_address_list(env->env_bcc->bcc_list,
2159 &addr_list);
2160
2161 if (r != MAIL_NO_ERROR) {
2162 res = r;
2163 goto free_list;
2164 }
2165
2166 bcc = mailimf_bcc_new(addr_list);
2167 if (bcc == NULL) {
2168 mailimf_address_list_free(addr_list);
2169 res = MAIL_ERROR_MEMORY;
2170 goto free_list;
2171 }
2172
2173 field = mailimf_field_new(MAILIMF_FIELD_BCC,
2174 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2175 NULL, NULL, NULL,
2176 NULL, NULL, NULL, NULL, bcc, NULL, NULL,
2177 NULL, NULL, NULL, NULL, NULL);
2178 if (field == NULL) {
2179 mailimf_bcc_free(bcc);
2180 res = MAIL_ERROR_MEMORY;
2181 goto free_list;
2182 }
2183
2184 r = clist_append(list, field);
2185 if (r != 0) {
2186 mailimf_field_free(field);
2187 res = MAIL_ERROR_MEMORY;
2188 goto free_list;
2189 }
2190 }
2191 }
2192
2193 if (env->env_in_reply_to != NULL) {
2194 struct mailimf_in_reply_to * in_reply_to;
2195 size_t cur_token;
2196 clist * msg_id_list;
2197
2198 cur_token = 0;
2199 r = mailimf_msg_id_list_parse(env->env_in_reply_to,
2200 strlen(env->env_in_reply_to), &cur_token, &msg_id_list);
2201
2202 switch (r) {
2203 case MAILIMF_NO_ERROR:
2204 in_reply_to = mailimf_in_reply_to_new(msg_id_list);
2205 if (in_reply_to == NULL) {
2206 clist_foreach(msg_id_list, (clist_func) mailimf_msg_id_free, NULL);
2207 clist_free(msg_id_list);
2208 res = MAIL_ERROR_MEMORY;
2209 goto free_list;
2210 }
2211
2212 field = mailimf_field_new(MAILIMF_FIELD_IN_REPLY_TO,
2213 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2214 NULL, NULL, NULL,
2215 NULL, NULL, NULL, NULL, NULL, NULL,
2216 in_reply_to,
2217 NULL, NULL, NULL, NULL, NULL);
2218 if (field == NULL) {
2219 mailimf_in_reply_to_free(in_reply_to);
2220 res = MAIL_ERROR_MEMORY;
2221 goto free_list;
2222 }
2223
2224 r = clist_append(list, field);
2225 if (r != 0) {
2226 mailimf_field_free(field);
2227 res = MAIL_ERROR_MEMORY;
2228 goto free_list;
2229 }
2230 break;
2231
2232 case MAILIMF_ERROR_PARSE:
2233 break;
2234
2235 default:
2236 res = maildriver_imf_error_to_mail_error(r);
2237 goto free_list;
2238 }
2239 }
2240
2241 if (env->env_message_id != NULL) {
2242 char * id;
2243 struct mailimf_message_id * msg_id;
2244 size_t cur_token;
2245
2246 cur_token = 0;
2247 r = mailimf_msg_id_parse(env->env_message_id, strlen(env->env_message_id),
2248 &cur_token, &id);
2249 switch (r) {
2250 case MAILIMF_NO_ERROR:
2251
2252 msg_id = mailimf_message_id_new(id);
2253 if (msg_id == NULL) {
2254 mailimf_msg_id_free(id);
2255 res = MAIL_ERROR_MEMORY;
2256 goto free_list;
2257 }
2258
2259 field = mailimf_field_new(MAILIMF_FIELD_MESSAGE_ID,
2260 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2261 NULL, NULL, NULL,
2262 NULL, NULL, NULL, NULL, NULL, msg_id, NULL,
2263 NULL, NULL, NULL, NULL, NULL);
2264 if (field == NULL) {
2265 mailimf_message_id_free(msg_id);
2266 res = MAIL_ERROR_MEMORY;
2267 goto free_list;
2268 }
2269
2270 r = clist_append(list, field);
2271 if (r != 0) {
2272 mailimf_field_free(field);
2273 res = MAIL_ERROR_MEMORY;
2274 goto free_list;
2275 }
2276 break;
2277
2278 case MAILIMF_ERROR_PARSE:
2279 break;
2280
2281 default:
2282 res = maildriver_imf_error_to_mail_error(r);
2283 goto free_list;
2284 }
2285 }
2286
2287 if (ref_str != NULL) {
2288 struct mailimf_references * references;
2289 size_t cur_token;
2290
2291 cur_token = 0;
2292 r = mailimf_references_parse(ref_str, ref_size,
2293 &cur_token, &references);
2294 switch (r) {
2295 case MAILIMF_NO_ERROR:
2296 field = mailimf_field_new(MAILIMF_FIELD_REFERENCES,
2297 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2298 NULL, NULL, NULL,
2299 NULL, NULL, NULL, NULL, NULL, NULL,
2300 NULL,
2301 references, NULL, NULL, NULL, NULL);
2302 if (field == NULL) {
2303 mailimf_references_free(references);
2304 res = MAIL_ERROR_MEMORY;
2305 goto free_list;
2306 }
2307
2308 r = clist_append(list, field);
2309 if (r < 0) {
2310 mailimf_field_free(field);
2311 res = MAIL_ERROR_MEMORY;
2312 goto free_list;
2313 }
2314 break;
2315
2316 case MAILIMF_ERROR_PARSE:
2317 break;
2318
2319 default:
2320 res = maildriver_imf_error_to_mail_error(r);
2321 goto free_list;
2322 }
2323 }
2324
2325 fields = mailimf_fields_new(list);
2326 if (fields == NULL) {
2327 res = MAIL_ERROR_MEMORY;
2328 goto free_list;
2329 }
2330
2331 * result = fields;
2332
2333 return MAIL_NO_ERROR;
2334
2335 free_list:
2336 clist_foreach(list, (clist_func) mailimf_field_free, NULL);
2337 clist_free(list);
2338 err:
2339 return res;
2340}
2341
2342int imap_get_msg_att_info(struct mailimap_msg_att * msg_att,
2343 uint32_t * puid,
2344 struct mailimap_envelope ** pimap_envelope,
2345 char ** preferences,
2346 size_t * pref_size,
2347 struct mailimap_msg_att_dynamic ** patt_dyn,
2348 struct mailimap_body ** pimap_body)
2349{
2350 clistiter * item_cur;
2351 uint32_t uid;
2352 struct mailimap_envelope * imap_envelope;
2353 char * references;
2354 size_t ref_size;
2355 struct mailimap_msg_att_dynamic * att_dyn;
2356 struct mailimap_body * imap_body;
2357
2358 uid = 0;
2359 imap_envelope = NULL;
2360 references = NULL;
2361 ref_size = 0;
2362 att_dyn = NULL;
2363 imap_body = NULL;
2364
2365 for(item_cur = clist_begin(msg_att->att_list) ; item_cur != NULL ;
2366 item_cur = clist_next(item_cur)) {
2367 struct mailimap_msg_att_item * item;
2368
2369 item = clist_content(item_cur);
2370
2371 switch (item->att_type) {
2372 case MAILIMAP_MSG_ATT_ITEM_STATIC:
2373 switch (item->att_data.att_static->att_type) {
2374 case MAILIMAP_MSG_ATT_BODYSTRUCTURE:
2375 if (imap_body == NULL)
2376 imap_body = item->att_data.att_static->att_data.att_bodystructure;
2377 break;
2378
2379 case MAILIMAP_MSG_ATT_ENVELOPE:
2380 if (imap_envelope == NULL) {
2381 imap_envelope = item->att_data.att_static->att_data.att_env;
2382 }
2383 break;
2384
2385 case MAILIMAP_MSG_ATT_UID:
2386 uid = item->att_data.att_static->att_data.att_uid;
2387 break;
2388
2389 case MAILIMAP_MSG_ATT_BODY_SECTION:
2390 if (references == NULL) {
2391 references = item->att_data.att_static->att_data.att_body_section->sec_body_part;
2392 ref_size = item->att_data.att_static->att_data.att_body_section->sec_length;
2393 }
2394 break;
2395 }
2396 break;
2397
2398 case MAILIMAP_MSG_ATT_ITEM_DYNAMIC:
2399 if (att_dyn == NULL) {
2400 att_dyn = item->att_data.att_dyn;
2401 }
2402 break;
2403 }
2404 }
2405
2406 if (puid != NULL)
2407 * puid = uid;
2408 if (pimap_envelope != NULL)
2409 * pimap_envelope = imap_envelope;
2410 if (preferences != NULL)
2411 * preferences = references;
2412 if (pref_size != NULL)
2413 * pref_size = ref_size;
2414 if (patt_dyn != NULL)
2415 * patt_dyn = att_dyn;
2416 if (pimap_body != NULL)
2417 * pimap_body = imap_body;
2418
2419 return MAIL_NO_ERROR;
2420}
2421
2422int
2423imap_fetch_result_to_envelop_list(clist * fetch_result,
2424 struct mailmessage_list * env_list)
2425{
2426 clistiter * cur;
2427 int r;
2428 unsigned int i;
2429
2430 i = 0;
2431
2432 for(cur = clist_begin(fetch_result) ; cur != NULL ;
2433 cur = clist_next(cur)) {
2434 struct mailimap_msg_att * msg_att;
2435 uint32_t uid;
2436 struct mailimap_envelope * imap_envelope;
2437 struct mailimap_msg_att_dynamic * att_dyn;
2438 char * references;
2439 size_t ref_size;
2440
2441 msg_att = clist_content(cur);
2442
2443 r = imap_get_msg_att_info(msg_att, &uid, &imap_envelope,
2444 &references, &ref_size,
2445 &att_dyn,
2446 NULL);
2447
2448 if (r == MAIL_NO_ERROR) {
2449 if (uid != 0) {
2450 while (i < carray_count(env_list->msg_tab)) {
2451 mailmessage * msg;
2452
2453 msg = carray_get(env_list->msg_tab, i);
2454
2455 if (uid == msg->msg_index) {
2456 struct mailimf_fields * fields;
2457 struct mail_flags * flags;
2458
2459 if (imap_envelope != NULL) {
2460 r = imap_env_to_fields(imap_envelope,
2461 references, ref_size, &fields);
2462 if (r == MAIL_NO_ERROR) {
2463 msg->msg_fields = fields;
2464 }
2465 }
2466
2467 if (att_dyn != NULL) {
2468 r = imap_flags_to_flags(att_dyn, &flags);
2469
2470 if (r == MAIL_NO_ERROR) {
2471 msg->msg_flags = flags;
2472 }
2473 }
2474
2475 i ++;
2476 break;
2477 }
2478
2479 i ++;
2480 }
2481 }
2482 }
2483 }
2484
2485 return MAIL_NO_ERROR;
2486}
2487
2488
2489int mailimf_date_time_to_imap_date(struct mailimf_date_time * date,
2490 struct mailimap_date ** result)
2491{
2492 struct mailimap_date * imap_date;
2493
2494 imap_date = mailimap_date_new(date->dt_day, date->dt_month, date->dt_year);
2495 if (imap_date == NULL)
2496 return MAIL_ERROR_MEMORY;
2497
2498 * result = imap_date;
2499
2500 return MAIL_NO_ERROR;
2501}
2502
2503
2504#if 0
2505int mail_search_to_imap_search(struct mail_search_key * key,
2506 struct mailimap_search_key ** result)
2507{
2508 struct mailimap_search_key * imap_key;
2509
2510 char * bcc;
2511 struct mailimap_date * before;
2512 char * body;
2513 char * cc;
2514 char * from;
2515 struct mailimap_date * on;
2516 struct mailimap_date * since;
2517 char * subject;
2518 char * text;
2519 char * to;
2520 char * header_name;
2521 char * header_value;
2522 size_t larger;
2523 struct mailimap_search_key * not;
2524 struct mailimap_search_key * or1;
2525 struct mailimap_search_key * or2;
2526 size_t smaller;
2527 clist * multiple;
2528 int type;
2529 clistiter * cur;
2530 int r;
2531 int res;
2532
2533 bcc = NULL;
2534 before = NULL;
2535 body = NULL;
2536 cc = NULL;
2537 from = NULL;
2538 on = NULL;
2539 since = NULL;
2540 subject = NULL;
2541 text = NULL;
2542 to = NULL;
2543 header_name = NULL;
2544 header_value = NULL;
2545 not = NULL;
2546 or1 = NULL;
2547 or2 = NULL;
2548 multiple = NULL;
2549 larger = 0;
2550 smaller = 0;
2551
2552 switch (key->sk_type) {
2553 case MAIL_SEARCH_KEY_ALL:
2554 type = MAILIMAP_SEARCH_KEY_ALL;
2555 break;
2556
2557 case MAIL_SEARCH_KEY_ANSWERED:
2558 type = MAILIMAP_SEARCH_KEY_ANSWERED;
2559 break;
2560
2561 case MAIL_SEARCH_KEY_BCC:
2562 type = MAILIMAP_SEARCH_KEY_BCC;
2563 bcc = strdup(key->sk_bcc);
2564 if (bcc == NULL) {
2565 res = MAIL_ERROR_MEMORY;
2566 goto err;
2567 }
2568 break;
2569
2570 case MAIL_SEARCH_KEY_BEFORE:
2571 type = MAILIMAP_SEARCH_KEY_BEFORE;
2572 r = mailimf_date_time_to_imap_date(key->sk_before, &before);
2573 if (r != MAIL_NO_ERROR) {
2574 res = r;
2575 goto err;
2576 }
2577 break;
2578
2579 case MAIL_SEARCH_KEY_BODY:
2580 type = MAILIMAP_SEARCH_KEY_BODY;
2581 body = strdup(key->sk_body);
2582 if (body == NULL) {
2583 res = MAIL_ERROR_MEMORY;
2584 goto err;
2585 }
2586 break;
2587
2588 case MAIL_SEARCH_KEY_CC:
2589 type = MAILIMAP_SEARCH_KEY_CC;
2590 cc = strdup(key->sk_cc);
2591 if (cc == NULL) {
2592 res = MAIL_ERROR_MEMORY;
2593 goto err;
2594 }
2595 break;
2596
2597 case MAIL_SEARCH_KEY_DELETED:
2598 type = MAILIMAP_SEARCH_KEY_DELETED;
2599 break;
2600
2601 case MAIL_SEARCH_KEY_FLAGGED:
2602 type = MAILIMAP_SEARCH_KEY_FLAGGED;
2603 break;
2604
2605 case MAIL_SEARCH_KEY_FROM:
2606 type = MAILIMAP_SEARCH_KEY_FROM;
2607 from = strdup(key->sk_from);
2608 if (from == NULL) {
2609 res = MAIL_ERROR_MEMORY;
2610 goto err;
2611 }
2612 break;
2613
2614 case MAIL_SEARCH_KEY_NEW:
2615 type = MAILIMAP_SEARCH_KEY_NEW;
2616 break;
2617
2618 case MAIL_SEARCH_KEY_OLD:
2619 type = MAILIMAP_SEARCH_KEY_OLD;
2620 break;
2621
2622 case MAIL_SEARCH_KEY_ON:
2623 type = MAILIMAP_SEARCH_KEY_ON;
2624 r = mailimf_date_time_to_imap_date(key->sk_on, &on);
2625 if (r != MAIL_NO_ERROR) {
2626 res = r;
2627 goto err;
2628 }
2629 break;
2630
2631 case MAIL_SEARCH_KEY_RECENT:
2632 type = MAILIMAP_SEARCH_KEY_RECENT;
2633 break;
2634
2635 case MAIL_SEARCH_KEY_SEEN:
2636 type = MAILIMAP_SEARCH_KEY_SEEN;
2637 break;
2638
2639 case MAIL_SEARCH_KEY_SINCE:
2640 type = MAILIMAP_SEARCH_KEY_SINCE;
2641 r = mailimf_date_time_to_imap_date(key->sk_since, &since);
2642 if (r != MAIL_NO_ERROR) {
2643 res = r;
2644 goto err;
2645 }
2646 break;
2647
2648 case MAIL_SEARCH_KEY_SUBJECT:
2649 type = MAILIMAP_SEARCH_KEY_SUBJECT;
2650 subject = strdup(key->sk_subject);
2651 if (subject == NULL) {
2652 res = MAIL_ERROR_MEMORY;
2653 goto err;
2654 }
2655 break;
2656
2657 case MAIL_SEARCH_KEY_TEXT:
2658 type = MAILIMAP_SEARCH_KEY_TEXT;
2659 text = strdup(key->sk_text);
2660 if (text == NULL) {
2661 res = MAIL_ERROR_MEMORY;
2662 goto err;
2663 }
2664 break;
2665
2666 case MAIL_SEARCH_KEY_TO:
2667 type = MAILIMAP_SEARCH_KEY_TO;
2668 to = strdup(key->sk_to);
2669 if (to == NULL) {
2670 return MAIL_ERROR_MEMORY;
2671 goto err;
2672 }
2673 break;
2674
2675 case MAIL_SEARCH_KEY_UNANSWERED:
2676 type = MAILIMAP_SEARCH_KEY_UNANSWERED;
2677 break;
2678
2679 case MAIL_SEARCH_KEY_UNDELETED:
2680 type = MAILIMAP_SEARCH_KEY_UNFLAGGED;
2681 break;
2682
2683 case MAIL_SEARCH_KEY_UNFLAGGED:
2684 type = MAILIMAP_SEARCH_KEY_UNANSWERED;
2685 break;
2686
2687 case MAIL_SEARCH_KEY_UNSEEN:
2688 type = MAILIMAP_SEARCH_KEY_UNSEEN;
2689 break;
2690
2691 case MAIL_SEARCH_KEY_HEADER:
2692 type = MAILIMAP_SEARCH_KEY_HEADER;
2693 header_name = strdup(key->sk_header_name);
2694 if (header_name == NULL) {
2695 res = MAIL_ERROR_MEMORY;
2696 goto err;
2697 }
2698 header_value = strdup(key->sk_header_value);
2699 if (header_value == NULL) {
2700 free(header_name);
2701 res = MAIL_ERROR_MEMORY;
2702 goto err;
2703 }
2704 break;
2705
2706 case MAIL_SEARCH_KEY_LARGER:
2707 type = MAILIMAP_SEARCH_KEY_LARGER;
2708 larger = key->sk_larger;
2709 break;
2710
2711 case MAIL_SEARCH_KEY_NOT:
2712 type = MAILIMAP_SEARCH_KEY_NOT;
2713 r = mail_search_to_imap_search(key->sk_not, &not);
2714 if (r != MAIL_NO_ERROR) {
2715 res = r;
2716 goto err;
2717 }
2718 break;
2719
2720 case MAIL_SEARCH_KEY_OR:
2721 type = MAILIMAP_SEARCH_KEY_OR;
2722 r = mail_search_to_imap_search(key->sk_or1, &or1);
2723 if (r != MAIL_NO_ERROR) {
2724 res = r;
2725 goto err;
2726 }
2727 r = mail_search_to_imap_search(key->sk_or2, &or2);
2728 if (r != MAIL_NO_ERROR) {
2729 mailimap_search_key_free(or1);
2730 res = r;
2731 goto err;
2732 }
2733 break;
2734
2735 case MAIL_SEARCH_KEY_SMALLER:
2736 type = MAILIMAP_SEARCH_KEY_SMALLER;
2737 smaller = key->sk_smaller;
2738 break;
2739
2740 case MAIL_SEARCH_KEY_MULTIPLE:
2741 multiple = clist_new();
2742 if (multiple == NULL) {
2743 res = MAIL_ERROR_MEMORY;
2744 goto err;
2745 }
2746
2747 type = MAILIMAP_SEARCH_KEY_MULTIPLE;
2748 for(cur = clist_begin(key->sk_multiple) ; cur != NULL ;
2749 cur = clist_next(cur)) {
2750 struct mail_search_key * key_elt;
2751 struct mailimap_search_key * imap_key_elt;
2752
2753 key_elt = clist_content(cur);
2754 r = mail_search_to_imap_search(key_elt, &imap_key_elt);
2755 if (r != MAIL_NO_ERROR) {
2756 res = r;
2757 goto free_list;
2758 }
2759
2760 r = clist_append(multiple, imap_key_elt);
2761 if (r != 0) {
2762 mailimap_search_key_free(imap_key_elt);
2763 res = MAIL_ERROR_MEMORY;
2764 goto free_list;
2765 }
2766 }
2767 break;
2768
2769 free_list:
2770 clist_foreach(multiple, (clist_func) mailimap_search_key_free, NULL);
2771 clist_free(multiple);
2772 goto err;
2773
2774 default:
2775 return MAIL_ERROR_INVAL;
2776 }
2777
2778 imap_key = mailimap_search_key_new(type, bcc, before, body, cc, from,
2779 NULL, on, since, subject, text,
2780 to, NULL, header_name,
2781 header_value, larger, not, or1, or2,
2782 NULL, NULL, NULL, smaller, NULL,
2783 NULL, multiple);
2784 if (imap_key == NULL) {
2785 res = MAIL_ERROR_MEMORY;
2786 goto free;
2787 }
2788
2789 * result = imap_key;
2790
2791 return MAIL_NO_ERROR;
2792
2793 free:
2794 if (bcc != NULL)
2795 free(bcc);
2796 if (before != NULL)
2797 mailimap_date_free(before);
2798 if (body != NULL)
2799 free(body);
2800 if (cc != NULL)
2801 free(cc);
2802 if (from != NULL)
2803 free(from);
2804 if (on != NULL)
2805 mailimap_date_free(on);
2806 if (since != NULL)
2807 mailimap_date_free(since);
2808 if (subject != NULL)
2809 free(subject);
2810 if (text != NULL)
2811 free(text);
2812 if (to != NULL)
2813 free(to);
2814 if (header_name != NULL)
2815 free(header_name);
2816 if (header_value != NULL)
2817 free(header_value);
2818 if (not != NULL)
2819 mailimap_search_key_free(not);
2820 if (or1 != NULL)
2821 mailimap_search_key_free(or1);
2822 if (or2 != NULL)
2823 mailimap_search_key_free(or2);
2824 clist_foreach(multiple, (clist_func) mailimap_search_key_free, NULL);
2825 clist_free(multiple);
2826 err:
2827 return res;
2828}
2829#endif
2830
2831
2832int msg_list_to_imap_set(clist * msg_list,
2833 struct mailimap_set ** result)
2834{
2835 struct mailimap_set * imap_set;
2836 clistiter * cur;
2837 int previous_valid;
2838 uint32_t first_seq;
2839 uint32_t previous;
2840 int r;
2841 int res;
2842
2843 imap_set = mailimap_set_new_empty();
2844 if (imap_set == NULL) {
2845 res = MAIL_ERROR_MEMORY;
2846 goto err;
2847 }
2848
2849 cur = clist_begin(msg_list);
2850 previous_valid = FALSE;
2851 first_seq = 0;
2852 previous = 0;
2853 while (1) {
2854 uint32_t * pindex;
2855
2856 if ((cur == NULL) && (previous_valid)) {
2857 if (first_seq == previous) {
2858 r = mailimap_set_add_single(imap_set, first_seq);
2859 if (r != MAILIMAP_NO_ERROR) {
2860 res = r;
2861 goto free;
2862 }
2863 }
2864 else {
2865 r = mailimap_set_add_interval(imap_set, first_seq, previous);
2866 if (r != MAILIMAP_NO_ERROR) {
2867 res = r;
2868 goto free;
2869 }
2870 }
2871 break;
2872 }
2873
2874 pindex = clist_content(cur);
2875
2876 if (!previous_valid) {
2877 first_seq = * pindex;
2878 previous_valid = TRUE;
2879 previous = * pindex;
2880 cur = clist_next(cur);
2881 }
2882 else {
2883 if (* pindex != previous + 1) {
2884 if (first_seq == previous) {
2885 r = mailimap_set_add_single(imap_set, first_seq);
2886 if (r != MAILIMAP_NO_ERROR) {
2887 res = r;
2888 goto free;
2889 }
2890 }
2891 else {
2892 r = mailimap_set_add_interval(imap_set, first_seq, previous);
2893 if (r != MAILIMAP_NO_ERROR) {
2894 res = r;
2895 goto free;
2896 }
2897 }
2898 previous_valid = FALSE;
2899 }
2900 else {
2901 previous = * pindex;
2902 cur = clist_next(cur);
2903 }
2904 }
2905 }
2906
2907 * result = imap_set;
2908
2909 return MAIL_NO_ERROR;
2910
2911 free:
2912 mailimap_set_free(imap_set);
2913 err:
2914 return res;
2915}
2916
2917
2918static int
2919uid_list_to_env_list(clist * fetch_result,
2920 struct mailmessage_list ** result,
2921 mailsession * session, mailmessage_driver * driver)
2922{
2923 clistiter * cur;
2924 struct mailmessage_list * env_list;
2925 int r;
2926 int res;
2927 carray * tab;
2928 unsigned int i;
2929 mailmessage * msg;
2930
2931 tab = carray_new(128);
2932 if (tab == NULL) {
2933 res = MAIL_ERROR_MEMORY;
2934 goto err;
2935 }
2936
2937 for(cur = clist_begin(fetch_result) ; cur != NULL ;
2938 cur = clist_next(cur)) {
2939 struct mailimap_msg_att * msg_att;
2940 clistiter * item_cur;
2941 uint32_t uid;
2942 size_t size;
2943
2944 msg_att = clist_content(cur);
2945
2946 uid = 0;
2947 size = 0;
2948 for(item_cur = clist_begin(msg_att->att_list) ; item_cur != NULL ;
2949 item_cur = clist_next(item_cur)) {
2950 struct mailimap_msg_att_item * item;
2951
2952 item = clist_content(item_cur);
2953
2954 switch (item->att_type) {
2955 case MAILIMAP_MSG_ATT_ITEM_STATIC:
2956 switch (item->att_data.att_static->att_type) {
2957 case MAILIMAP_MSG_ATT_UID:
2958 uid = item->att_data.att_static->att_data.att_uid;
2959 break;
2960
2961 case MAILIMAP_MSG_ATT_RFC822_SIZE:
2962 size = item->att_data.att_static->att_data.att_rfc822_size;
2963 break;
2964 }
2965 break;
2966 }
2967 }
2968
2969 msg = mailmessage_new();
2970 if (msg == NULL) {
2971 res = MAIL_ERROR_MEMORY;
2972 goto free_list;
2973 }
2974
2975 r = mailmessage_init(msg, session, driver, uid, size);
2976 if (r != MAIL_NO_ERROR) {
2977 res = r;
2978 goto free_msg;
2979 }
2980
2981 r = carray_add(tab, msg, NULL);
2982 if (r < 0) {
2983 res = MAIL_ERROR_MEMORY;
2984 goto free_msg;
2985 }
2986 }
2987
2988 env_list = mailmessage_list_new(tab);
2989 if (env_list == NULL) {
2990 res = MAIL_ERROR_MEMORY;
2991 goto free_list;
2992 }
2993
2994 * result = env_list;
2995
2996 return MAIL_NO_ERROR;
2997
2998 free_msg:
2999 mailmessage_free(msg);
3000 free_list:
3001 for(i = 0 ; i < carray_count(tab) ; i++)
3002 mailmessage_free(carray_get(tab, i));
3003 err:
3004 return res;
3005}
3006
3007
3008/*
3009 MAILIMAP_FLAG_FETCH_RECENT,
3010 MAILIMAP_FLAG_FETCH_OTHER
3011
3012 MAILIMAP_FLAG_ANSWERED,
3013 MAILIMAP_FLAG_FLAGGED,
3014 MAILIMAP_FLAG_DELETED,
3015 MAILIMAP_FLAG_SEEN,
3016 MAILIMAP_FLAG_DRAFT,
3017 MAILIMAP_FLAG_KEYWORD,
3018 MAILIMAP_FLAG_EXTENSION
3019*/
3020
3021static int imap_flags_to_flags(struct mailimap_msg_att_dynamic * att_dyn,
3022 struct mail_flags ** result)
3023{
3024 struct mail_flags * flags;
3025 clist * flag_list;
3026 clistiter * cur;
3027
3028 flags = mail_flags_new_empty();
3029 if (flags == NULL)
3030 goto err;
3031 flags->fl_flags = 0;
3032
3033 flag_list = att_dyn->att_list;
3034 if (flag_list != NULL) {
3035 for(cur = clist_begin(flag_list) ; cur != NULL ;
3036 cur = clist_next(cur)) {
3037 struct mailimap_flag_fetch * flag_fetch;
3038
3039 flag_fetch = clist_content(cur);
3040 if (flag_fetch->fl_type == MAILIMAP_FLAG_FETCH_RECENT)
3041 flags->fl_flags |= MAIL_FLAG_NEW;
3042 else {
3043 char * keyword;
3044 int r;
3045
3046 switch (flag_fetch->fl_flag->fl_type) {
3047 case MAILIMAP_FLAG_ANSWERED:
3048 flags->fl_flags |= MAIL_FLAG_ANSWERED;
3049 break;
3050 case MAILIMAP_FLAG_FLAGGED:
3051 flags->fl_flags |= MAIL_FLAG_FLAGGED;
3052 break;
3053 case MAILIMAP_FLAG_DELETED:
3054 flags->fl_flags |= MAIL_FLAG_DELETED;
3055 break;
3056 case MAILIMAP_FLAG_SEEN:
3057 flags->fl_flags |= MAIL_FLAG_SEEN;
3058 break;
3059 case MAILIMAP_FLAG_DRAFT:
3060 keyword = strdup("Draft");
3061 if (keyword == NULL)
3062 goto free;
3063 r = clist_append(flags->fl_extension, keyword);
3064 if (r < 0) {
3065 free(keyword);
3066 goto free;
3067 }
3068 break;
3069 case MAILIMAP_FLAG_KEYWORD:
3070 if (strcasecmp(flag_fetch->fl_flag->fl_data.fl_keyword,
3071 "$Forwarded") == 0) {
3072 flags->fl_flags |= MAIL_FLAG_FORWARDED;
3073 }
3074 else {
3075 keyword = strdup(flag_fetch->fl_flag->fl_data.fl_keyword);
3076 if (keyword == NULL)
3077 goto free;
3078 r = clist_append(flags->fl_extension, keyword);
3079 if (r < 0) {
3080 free(keyword);
3081 goto free;
3082 }
3083 }
3084 break;
3085 case MAILIMAP_FLAG_EXTENSION:
3086 /* do nothing */
3087 break;
3088 }
3089 }
3090 }
3091 /*
3092 MAIL_FLAG_NEW was set for \Recent messages.
3093 Correct this flag for \Seen messages by unsetting it.
3094 */
3095 if ((flags->fl_flags & MAIL_FLAG_SEEN) && (flags->fl_flags & MAIL_FLAG_NEW)) {
3096 flags->fl_flags &= ~MAIL_FLAG_NEW;
3097 }
3098 }
3099
3100 * result = flags;
3101
3102 return MAIL_NO_ERROR;
3103
3104 free:
3105 mail_flags_free(flags);
3106 err:
3107 return MAIL_ERROR_MEMORY;
3108}
3109
3110static int flags_to_imap_flags(struct mail_flags * flags,
3111 struct mailimap_store_att_flags ** result)
3112{
3113 struct mailimap_flag * flag;
3114 struct mailimap_flag_list * flag_list;
3115 struct mailimap_store_att_flags * att_flags;
3116 int res;
3117 clistiter * cur;
3118 int r;
3119
3120 flag_list = mailimap_flag_list_new_empty();
3121 if (flag_list == NULL) {
3122 res = MAIL_ERROR_MEMORY;
3123 goto err;
3124 }
3125
3126 if ((flags->fl_flags & MAIL_FLAG_DELETED) != 0) {
3127 flag = mailimap_flag_new_deleted();
3128 if (flag == NULL) {
3129 res = MAIL_ERROR_MEMORY;
3130 goto free_flag_list;
3131 }
3132 r = mailimap_flag_list_add(flag_list, flag);
3133 if (r != MAILIMAP_NO_ERROR) {
3134 mailimap_flag_free(flag);
3135 res = MAIL_ERROR_MEMORY;
3136 goto free_flag_list;
3137 }
3138 }
3139
3140 if ((flags->fl_flags & MAIL_FLAG_FLAGGED) != 0) {
3141 flag = mailimap_flag_new_flagged();
3142 if (flag == NULL) {
3143 res = MAIL_ERROR_MEMORY;
3144 goto free_flag_list;
3145 }
3146 r = mailimap_flag_list_add(flag_list, flag);
3147 if (r != MAILIMAP_NO_ERROR) {
3148 mailimap_flag_free(flag);
3149 res = MAIL_ERROR_MEMORY;
3150 goto free_flag_list;
3151 }
3152 }
3153
3154 if ((flags->fl_flags & MAIL_FLAG_SEEN) != 0) {
3155 flag = mailimap_flag_new_seen();
3156 if (flag == NULL) {
3157 res = MAIL_ERROR_MEMORY;
3158 goto free_flag_list;
3159 }
3160 r = mailimap_flag_list_add(flag_list, flag);
3161 if (r != MAILIMAP_NO_ERROR) {
3162 res = MAIL_ERROR_MEMORY;
3163 goto free_flag_list;
3164 }
3165 }
3166
3167 if ((flags->fl_flags & MAIL_FLAG_ANSWERED) != 0) {
3168 flag = mailimap_flag_new_answered();
3169 if (flag == NULL) {
3170 res = MAIL_ERROR_MEMORY;
3171 goto free_flag_list;
3172 }
3173 r = mailimap_flag_list_add(flag_list, flag);
3174 if (r != MAILIMAP_NO_ERROR) {
3175 mailimap_flag_free(flag);
3176 res = MAIL_ERROR_MEMORY;
3177 goto free_flag_list;
3178 }
3179 }
3180
3181 if ((flags->fl_flags & MAIL_FLAG_FORWARDED) != 0) {
3182 char * flag_str;
3183
3184 flag_str = strdup("$Forwarded");
3185 if (flag_str == NULL) {
3186 res = MAIL_ERROR_MEMORY;
3187 goto free_flag_list;
3188 }
3189 flag = mailimap_flag_new_flag_keyword(flag_str);
3190 if (flag == NULL) {
3191 free(flag_str);
3192 res = MAIL_ERROR_MEMORY;
3193 goto free_flag_list;
3194 }
3195 r = mailimap_flag_list_add(flag_list, flag);
3196 if (r != MAILIMAP_NO_ERROR) {
3197 mailimap_flag_free(flag);
3198 res = MAIL_ERROR_MEMORY;
3199 goto free_flag_list;
3200 }
3201 }
3202
3203 for(cur = clist_begin(flags->fl_extension) ; cur != NULL ;
3204 cur = clist_next(cur)) {
3205 char * flag_str;
3206
3207 flag_str = clist_content(cur);
3208
3209 if (strcasecmp(flag_str, "Draft") == 0) {
3210 flag = mailimap_flag_new_draft();
3211 if (flag == NULL) {
3212 res = MAIL_ERROR_MEMORY;
3213 goto free_flag_list;
3214 }
3215 r = mailimap_flag_list_add(flag_list, flag);
3216 if (r != MAILIMAP_NO_ERROR) {
3217 mailimap_flag_free(flag);
3218 res = MAIL_ERROR_MEMORY;
3219 goto free_flag_list;
3220 }
3221 }
3222 else {
3223 flag_str = strdup(flag_str);
3224 if (flag_str == NULL) {
3225 res = MAIL_ERROR_MEMORY;
3226 goto free_flag_list;
3227 }
3228 flag = mailimap_flag_new_flag_keyword(flag_str);
3229 if (flag == NULL) {
3230 free(flag_str);
3231 res = MAIL_ERROR_MEMORY;
3232 goto free_flag_list;
3233 }
3234 r = mailimap_flag_list_add(flag_list, flag);
3235 if (r != MAILIMAP_NO_ERROR) {
3236 mailimap_flag_free(flag);
3237 res = MAIL_ERROR_MEMORY;
3238 goto free_flag_list;
3239 }
3240 }
3241 }
3242
3243 att_flags = mailimap_store_att_flags_new_set_flags_silent(flag_list);
3244 if (att_flags == NULL) {
3245 res = MAIL_ERROR_MEMORY;
3246 goto free_flag_list;
3247 }
3248
3249 * result = att_flags;
3250
3251 return MAIL_NO_ERROR;
3252
3253 free_flag_list:
3254 mailimap_flag_list_free(flag_list);
3255 err:
3256 return res;
3257}
3258
3259
3260static int
3261imap_fetch_result_to_flags(clist * fetch_result, uint32_t index,
3262 struct mail_flags ** result)
3263{
3264 clistiter * cur;
3265 int r;
3266
3267 for(cur = clist_begin(fetch_result) ; cur != NULL ;
3268 cur = clist_next(cur)) {
3269 struct mailimap_msg_att * msg_att;
3270 clistiter * item_cur;
3271 uint32_t uid;
3272 struct mailimap_msg_att_dynamic * att_dyn;
3273
3274 msg_att = clist_content(cur);
3275
3276 uid = 0;
3277 att_dyn = NULL;
3278
3279 for(item_cur = clist_begin(msg_att->att_list) ; item_cur != NULL ;
3280 item_cur = clist_next(item_cur)) {
3281 struct mailimap_msg_att_item * item;
3282
3283 item = clist_content(item_cur);
3284
3285 if (item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) {
3286 switch (item->att_data.att_static->att_type) {
3287 case MAILIMAP_MSG_ATT_UID:
3288 uid = item->att_data.att_static->att_data.att_uid;
3289 break;
3290 }
3291 }
3292 else if (item->att_type == MAILIMAP_MSG_ATT_ITEM_DYNAMIC) {
3293 if (att_dyn == NULL) {
3294 att_dyn = item->att_data.att_dyn;
3295 }
3296 }
3297 }
3298
3299 if (uid != 0) {
3300 if (uid == index) {
3301 struct mail_flags * flags;
3302
3303 if (att_dyn != NULL) {
3304 r = imap_flags_to_flags(att_dyn, &flags);
3305
3306 if (r == MAIL_NO_ERROR) {
3307 * result = flags;
3308 return MAIL_NO_ERROR;
3309 }
3310 }
3311 }
3312 }
3313 }
3314
3315 return MAIL_ERROR_MSG_NOT_FOUND;
3316}
3317
3318
3319int imap_fetch_flags(mailimap * imap,
3320 uint32_t index, struct mail_flags ** result)
3321{
3322 struct mailimap_fetch_att * fetch_att;
3323 struct mailimap_fetch_type * fetch_type;
3324 struct mailimap_set * set;
3325 int r;
3326 int res;
3327 clist * fetch_result;
3328 struct mail_flags * flags;
3329
3330 fetch_type = mailimap_fetch_type_new_fetch_att_list_empty();
3331 if (fetch_type == NULL) {
3332 res = MAIL_ERROR_MEMORY;
3333 goto err;
3334 }
3335
3336 fetch_att = mailimap_fetch_att_new_uid();
3337 if (fetch_att == NULL) {
3338 res = MAIL_ERROR_MEMORY;
3339 goto free_fetch_type;
3340 }
3341
3342 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
3343 if (r != MAILIMAP_NO_ERROR) {
3344 mailimap_fetch_att_free(fetch_att);
3345 res = MAIL_ERROR_MEMORY;
3346 goto free_fetch_type;
3347 }
3348
3349 fetch_att = mailimap_fetch_att_new_flags();
3350 if (fetch_att == NULL) {
3351 res = MAIL_ERROR_MEMORY;
3352 goto free_fetch_type;
3353 }
3354
3355 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
3356 if (r != MAILIMAP_NO_ERROR) {
3357 mailimap_fetch_att_free(fetch_att);
3358 res = MAIL_ERROR_MEMORY;
3359 goto free_fetch_type;
3360 }
3361
3362 set = mailimap_set_new_single(index);
3363 if (set == NULL) {
3364 res = MAIL_ERROR_MEMORY;
3365 goto free_fetch_type;
3366 }
3367
3368 r = mailimap_uid_fetch(imap, set, fetch_type, &fetch_result);
3369
3370 mailimap_fetch_type_free(fetch_type);
3371 mailimap_set_free(set);
3372
3373 switch (r) {
3374 case MAILIMAP_NO_ERROR:
3375 break;
3376 default:
3377 return imap_error_to_mail_error(r);
3378 }
3379
3380 r = imap_fetch_result_to_flags(fetch_result, index, &flags);
3381 mailimap_fetch_list_free(fetch_result);
3382
3383 if (r != MAIL_NO_ERROR) {
3384 res = r;
3385 goto err;
3386 }
3387
3388 * result = flags;
3389
3390 return MAIL_NO_ERROR;
3391
3392 free_fetch_type:
3393 mailimap_fetch_type_free(fetch_type);
3394 err:
3395 return res;
3396}
3397
3398int imap_store_flags(mailimap * imap, uint32_t first, uint32_t last,
3399 struct mail_flags * flags)
3400{
3401 struct mailimap_store_att_flags * att_flags;
3402 struct mailimap_set * set;
3403 int r;
3404 int res;
3405
3406 set = mailimap_set_new_interval(first, last);
3407 if (set == NULL) {
3408 res = MAIL_ERROR_MEMORY;
3409 goto err;
3410 }
3411
3412 r = flags_to_imap_flags(flags, &att_flags);
3413 if (r != MAIL_NO_ERROR) {
3414 res = r;
3415 goto free_set;
3416 }
3417
3418 r = mailimap_uid_store(imap, set, att_flags);
3419 if (r != MAILIMAP_NO_ERROR) {
3420 res = imap_error_to_mail_error(r);
3421 goto free_flag;
3422 }
3423
3424 mailimap_store_att_flags_free(att_flags);
3425 mailimap_set_free(set);
3426
3427 return MAIL_NO_ERROR;
3428
3429 free_flag:
3430 mailimap_store_att_flags_free(att_flags);
3431 free_set:
3432 mailimap_set_free(set);
3433 err:
3434 return res;
3435}
3436
3437
3438
3439
3440int imap_get_messages_list(mailimap * imap,
3441 mailsession * session, mailmessage_driver * driver,
3442 uint32_t first_index,
3443 struct mailmessage_list ** result)
3444{
3445 struct mailmessage_list * env_list;
3446 int r;
3447 struct mailimap_fetch_att * fetch_att;
3448 struct mailimap_fetch_type * fetch_type;
3449 struct mailimap_set * set;
3450 clist * fetch_result;
3451 int res;
3452
3453 set = mailimap_set_new_interval(first_index, 0);
3454 if (set == NULL) {
3455 res = MAIL_ERROR_MEMORY;
3456 goto err;
3457 }
3458
3459 fetch_type = mailimap_fetch_type_new_fetch_att_list_empty();
3460 if (fetch_type == NULL) {
3461 res = MAIL_ERROR_MEMORY;
3462 goto free_set;
3463 }
3464
3465 fetch_att = mailimap_fetch_att_new_uid();
3466 if (fetch_att == NULL) {
3467 res = MAIL_ERROR_MEMORY;
3468 goto free_fetch_type;
3469 }
3470
3471 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
3472 if (r != MAILIMAP_NO_ERROR) {
3473 mailimap_fetch_att_free(fetch_att);
3474 res = MAIL_ERROR_MEMORY;
3475 goto free_fetch_type;
3476 }
3477
3478 fetch_att = mailimap_fetch_att_new_rfc822_size();
3479 if (fetch_att == NULL) {
3480 res = MAIL_ERROR_MEMORY;
3481 goto free_fetch_type;
3482 }
3483
3484 r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
3485 if (r != MAILIMAP_NO_ERROR) {
3486 mailimap_fetch_att_free(fetch_att);
3487 res = MAIL_ERROR_MEMORY;
3488 goto free_fetch_type;
3489 }
3490
3491 r = mailimap_uid_fetch(imap, set,
3492 fetch_type, &fetch_result);
3493
3494 mailimap_fetch_type_free(fetch_type);
3495 mailimap_set_free(set);
3496
3497 if (r != MAILIMAP_NO_ERROR) {
3498 res = imap_error_to_mail_error(r);
3499 goto err;
3500 }
3501
3502 r = uid_list_to_env_list(fetch_result, &env_list, session, driver);
3503 mailimap_fetch_list_free(fetch_result);
3504
3505 * result = env_list;
3506
3507 return MAIL_NO_ERROR;
3508
3509 free_fetch_type:
3510 mailimap_fetch_type_free(fetch_type);
3511 free_set:
3512 mailimap_set_free(set);
3513 err:
3514 return res;
3515}
3516
3517static void generate_key_from_message(char * key, size_t size,
3518 mailmessage * msg_info,
3519 int type)
3520{
3521 switch (type) {
3522 case MAILIMAP_MSG_ATT_RFC822:
3523 snprintf(key, size, "%s-rfc822", msg_info->msg_uid);
3524 break;
3525 case MAILIMAP_MSG_ATT_RFC822_HEADER:
3526 snprintf(key, size, "%s-rfc822-header", msg_info->msg_uid);
3527 break;
3528 case MAILIMAP_MSG_ATT_RFC822_TEXT:
3529 snprintf(key, size, "%s-rfc822-text", msg_info->msg_uid);
3530 break;
3531 case MAILIMAP_MSG_ATT_ENVELOPE:
3532 snprintf(key, size, "%s-envelope", msg_info->msg_uid);
3533 break;
3534 }
3535}
3536
3537int
3538imapdriver_get_cached_envelope(struct mail_cache_db * cache_db,
3539 MMAPString * mmapstr,
3540 mailsession * session, mailmessage * msg,
3541 struct mailimf_fields ** result)
3542{
3543#if 0
3544 mailsession * imap_session;
3545#endif
3546 mailimap * imap;
3547 int r;
3548 struct mailimf_fields * fields;
3549 int res;
3550 char keyname[PATH_MAX];
3551
3552#if 0
3553 imap_session = cached_session_get_ancestor(session);
3554 imap = ((struct imap_session_state_data *) (imap_session->data))->session;
3555#endif
3556 imap = cached_session_get_imap_session(session);
3557
3558 generate_key_from_message(keyname, PATH_MAX,
3559 msg, MAILIMAP_MSG_ATT_ENVELOPE);
3560
3561 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields);
3562 if (r != MAIL_NO_ERROR) {
3563 res = r;
3564 goto err;
3565 }
3566
3567 * result = fields;
3568
3569 return MAIL_NO_ERROR;
3570
3571err:
3572 return res;
3573}
3574
3575int
3576imapdriver_write_cached_envelope(struct mail_cache_db * cache_db,
3577 MMAPString * mmapstr,
3578 mailsession * session, mailmessage * msg,
3579 struct mailimf_fields * fields)
3580{
3581 char keyname[PATH_MAX];
3582 int r;
3583 int res;
3584
3585 generate_key_from_message(keyname, PATH_MAX,
3586 msg, MAILIMAP_MSG_ATT_ENVELOPE);
3587
3588 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields);
3589 if (r != MAIL_NO_ERROR) {
3590 res = r;
3591 goto err;
3592 }
3593
3594 return MAIL_NO_ERROR;
3595
3596err:
3597 return res;
3598}
3599
diff --git a/kmicromail/libetpan/generic/imapdriver_tools.h b/kmicromail/libetpan/generic/imapdriver_tools.h
new file mode 100644
index 0000000..6582a31
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_tools.h
@@ -0,0 +1,113 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef IMAPDRIVER_TOOLS_H
37
38#define IMAPDRIVER_TOOLS_H
39
40#include "mailimap.h"
41#include "mailmime.h"
42#include "imapdriver_types.h"
43#include "mail_cache_db.h"
44
45#ifdef __cplusplus
46extern "C" {
47#endif
48
49int imap_list_to_list(clist * imap_list, struct mail_list ** result);
50
51int
52section_to_imap_section(struct mailmime_section * section, int type,
53 struct mailimap_section ** result);
54
55int imap_get_msg_att_info(struct mailimap_msg_att * msg_att,
56 uint32_t * puid,
57 struct mailimap_envelope ** pimap_envelope,
58 char ** preferences,
59 size_t * pref_size,
60 struct mailimap_msg_att_dynamic ** patt_dyn,
61 struct mailimap_body ** pimap_body);
62
63int imap_add_envelope_fetch_att(struct mailimap_fetch_type * fetch_type);
64
65int imap_env_to_fields(struct mailimap_envelope * env,
66 char * ref_str, size_t ref_size,
67 struct mailimf_fields ** result);
68
69int
70imap_fetch_result_to_envelop_list(clist * fetch_result,
71 struct mailmessage_list * env_list);
72
73int imap_body_to_body(struct mailimap_body * imap_body,
74 struct mailmime ** result);
75
76#if 0
77int mail_search_to_imap_search(struct mail_search_key * key,
78 struct mailimap_search_key ** result);
79#endif
80
81int msg_list_to_imap_set(clist * msg_list,
82 struct mailimap_set ** result);
83
84int imap_error_to_mail_error(int error);
85
86int imap_store_flags(mailimap * imap, uint32_t first, uint32_t last,
87 struct mail_flags * flags);
88
89int imap_fetch_flags(mailimap * imap,
90 uint32_t index, struct mail_flags ** result);
91
92int imap_get_messages_list(mailimap * imap,
93 mailsession * session, mailmessage_driver * driver,
94 uint32_t first_index,
95 struct mailmessage_list ** result);
96
97int
98imapdriver_get_cached_envelope(struct mail_cache_db * cache_db,
99 MMAPString * mmapstr,
100 mailsession * session, mailmessage * msg,
101 struct mailimf_fields ** result);
102
103int
104imapdriver_write_cached_envelope(struct mail_cache_db * cache_db,
105 MMAPString * mmapstr,
106 mailsession * session, mailmessage * msg,
107 struct mailimf_fields * fields);
108
109#ifdef __cplusplus
110}
111#endif
112
113#endif
diff --git a/kmicromail/libetpan/generic/imapdriver_types.h b/kmicromail/libetpan/generic/imapdriver_types.h
new file mode 100644
index 0000000..d4e216d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapdriver_types.h
@@ -0,0 +1,144 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef IMAPDRIVER_TYPES_H
37
38#define IMAPDRIVER_TYPES_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/mailimap.h>
43#include <libetpan/maildriver_types.h>
44#include <libetpan/generic_cache_types.h>
45#include <libetpan/mailstorage_types.h>
46
47#ifdef __cplusplus
48extern "C" {
49#endif
50
51/* IMAP driver for session */
52
53struct imap_session_state_data {
54 mailimap * imap_session;
55 char * imap_mailbox;
56 struct mail_flags_store * imap_flags_store;
57};
58
59enum {
60 IMAP_SECTION_MESSAGE,
61 IMAP_SECTION_HEADER,
62 IMAP_SECTION_MIME,
63 IMAP_SECTION_BODY
64};
65
66/* cached IMAP driver for session */
67
68enum {
69 IMAPDRIVER_CACHED_SET_CACHE_DIRECTORY = 1,
70};
71
72struct imap_cached_session_state_data {
73 mailsession * imap_ancestor;
74 char * imap_quoted_mb;
75 char imap_cache_directory[PATH_MAX];
76 carray * imap_uid_list;
77};
78
79
80/* IMAP storage */
81
82/*
83 imap_mailstorage is the state data specific to the IMAP4rev1 storage.
84
85 - servername this is the name of the IMAP4rev1 server
86
87 - port is the port to connect to, on the server.
88 you give 0 to use the default port.
89
90 - command, if non-NULL the command used to connect to the
91 server instead of allowing normal TCP connections to be used.
92
93 - connection_type is the type of socket layer to use.
94 The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
95 CONNECTION_TYPE_TRY_STARTTLS, CONNECTION_TYPE_TLS or
96 CONNECTION_TYPE_COMMAND.
97
98 - auth_type is the authenticate mechanism to use.
99 The value can be IMAP_AUTH_TYPE_PLAIN.
100 Other values are not yet implemented.
101
102 - login is the login of the IMAP4rev1 account.
103
104 - password is the password of the IMAP4rev1 account.
105
106 - cached if this value is != 0, a persistant cache will be
107 stored on local system.
108
109 - cache_directory is the location of the cache
110*/
111
112struct imap_mailstorage {
113 char * imap_servername;
114 uint16_t imap_port;
115 char * imap_command;
116 int imap_connection_type;
117
118 int imap_auth_type;
119 char * imap_login;
120 char * imap_password;
121
122 int imap_cached;
123 char * imap_cache_directory;
124};
125
126/* this is the type of IMAP4rev1 authentication */
127
128enum {
129 IMAP_AUTH_TYPE_PLAIN, /* plain text authentication */
130 IMAP_AUTH_TYPE_SASL_ANONYMOUS, /* SASL anonymous */
131 IMAP_AUTH_TYPE_SASL_CRAM_MD5, /* SASL CRAM MD5 */
132 IMAP_AUTH_TYPE_SASL_KERBEROS_V4, /* SASL KERBEROS V4 */
133 IMAP_AUTH_TYPE_SASL_PLAIN, /* SASL plain */
134 IMAP_AUTH_TYPE_SASL_SCRAM_MD5, /* SASL SCRAM MD5 */
135 IMAP_AUTH_TYPE_SASL_GSSAPI, /* SASL GSSAPI */
136 IMAP_AUTH_TYPE_SASL_DIGEST_MD5, /* SASL digest MD5 */
137};
138
139
140#ifdef __cplusplus
141}
142#endif
143
144#endif
diff --git a/kmicromail/libetpan/generic/imapstorage.c b/kmicromail/libetpan/generic/imapstorage.c
new file mode 100644
index 0000000..e8683d8
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapstorage.c
@@ -0,0 +1,297 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "imapstorage.h"
37
38#include <stdlib.h>
39#include <string.h>
40
41#include "mail.h"
42#include "imapdriver.h"
43#include "imapdriver_cached.h"
44#include "mailstorage_tools.h"
45#include "maildriver.h"
46
47/* imap storage */
48
49#define IMAP_DEFAULT_PORT 143
50#define IMAPS_DEFAULT_PORT 993
51
52static int imap_mailstorage_connect(struct mailstorage * storage);
53static int
54imap_mailstorage_get_folder_session(struct mailstorage * storage,
55 char * pathname, mailsession ** result);
56static void imap_mailstorage_uninitialize(struct mailstorage * storage);
57
58static mailstorage_driver imap_mailstorage_driver = {
59 .sto_name = "imap",
60 .sto_connect = imap_mailstorage_connect,
61 .sto_get_folder_session = imap_mailstorage_get_folder_session,
62 .sto_uninitialize = imap_mailstorage_uninitialize,
63};
64
65int imap_mailstorage_init(struct mailstorage * storage,
66 char * imap_servername, uint16_t imap_port,
67 char * imap_command,
68 int imap_connection_type, int imap_auth_type,
69 char * imap_login, char * imap_password,
70 int imap_cached, char * imap_cache_directory)
71{
72 struct imap_mailstorage * imap_storage;
73
74 imap_storage = malloc(sizeof(struct imap_mailstorage));
75 if (imap_storage == NULL)
76 goto err;
77
78 imap_storage->imap_servername = strdup(imap_servername);
79 if (imap_storage->imap_servername == NULL)
80 goto free;
81
82 imap_storage->imap_connection_type = imap_connection_type;
83
84 if (imap_port == 0) {
85 switch (imap_connection_type) {
86 case CONNECTION_TYPE_PLAIN:
87 case CONNECTION_TYPE_TRY_STARTTLS:
88 case CONNECTION_TYPE_STARTTLS:
89 case CONNECTION_TYPE_COMMAND:
90 case CONNECTION_TYPE_COMMAND_TRY_STARTTLS:
91 case CONNECTION_TYPE_COMMAND_STARTTLS:
92 imap_port = IMAP_DEFAULT_PORT;
93 break;
94
95 case CONNECTION_TYPE_TLS:
96 case CONNECTION_TYPE_COMMAND_TLS:
97 imap_port = IMAPS_DEFAULT_PORT;
98 break;
99 }
100 }
101
102 imap_storage->imap_port = imap_port;
103
104 if (imap_command != NULL) {
105 imap_storage->imap_command = strdup(imap_command);
106 if (imap_storage->imap_command == NULL)
107 goto free_servername;
108 }
109 else
110 imap_storage->imap_command = NULL;
111
112 imap_storage->imap_auth_type = imap_auth_type;
113
114 if (imap_login != NULL) {
115 imap_storage->imap_login = strdup(imap_login);
116 if (imap_storage->imap_login == NULL)
117 goto free_command;
118 }
119 else
120 imap_storage->imap_login = NULL;
121
122 if (imap_password != NULL) {
123 imap_storage->imap_password = strdup(imap_password);
124 if (imap_storage->imap_password == NULL)
125 goto free_login;
126 }
127 else
128 imap_storage->imap_password = NULL;
129
130 imap_storage->imap_cached = imap_cached;
131
132 if (imap_cached && (imap_cache_directory != NULL)) {
133 imap_storage->imap_cache_directory = strdup(imap_cache_directory);
134 if (imap_storage->imap_cache_directory == NULL)
135 goto free_password;
136 }
137 else {
138 imap_storage->imap_cached = FALSE;
139 imap_storage->imap_cache_directory = NULL;
140 }
141
142 storage->sto_data = imap_storage;
143 storage->sto_driver = &imap_mailstorage_driver;
144
145 return MAIL_NO_ERROR;
146
147 free_password:
148 free(imap_storage->imap_password);
149 free_login:
150 free(imap_storage->imap_login);
151 free_command:
152 free(imap_storage->imap_command);
153 free_servername:
154 free(imap_storage->imap_servername);
155 free:
156 free(imap_storage);
157 err:
158 return MAIL_ERROR_MEMORY;
159}
160
161static void imap_mailstorage_uninitialize(struct mailstorage * storage)
162{
163 struct imap_mailstorage * imap_storage;
164
165 imap_storage = storage->sto_data;
166
167 if (imap_storage->imap_cache_directory != NULL)
168 free(imap_storage->imap_cache_directory);
169 if (imap_storage->imap_password != NULL)
170 free(imap_storage->imap_password);
171 if (imap_storage->imap_login != NULL)
172 free(imap_storage->imap_login);
173 if (imap_storage->imap_command != NULL)
174 free(imap_storage->imap_command);
175 free(imap_storage->imap_servername);
176 free(imap_storage);
177
178 storage->sto_data = NULL;
179}
180
181static int imap_connect(struct mailstorage * storage,
182 mailsession ** result)
183{
184 struct imap_mailstorage * imap_storage;
185 mailsession_driver * driver;
186 int r;
187 int res;
188 mailsession * session;
189
190 imap_storage = storage->sto_data;
191
192 if (imap_storage->imap_cached)
193 driver = imap_cached_session_driver;
194 else
195 driver = imap_session_driver;
196
197 r = mailstorage_generic_connect(driver,
198 imap_storage->imap_servername,
199 imap_storage->imap_port,
200 imap_storage->imap_command,
201 imap_storage->imap_connection_type,
202 IMAPDRIVER_CACHED_SET_CACHE_DIRECTORY,
203 imap_storage->imap_cache_directory,
204 0, NULL,
205 &session);
206 switch (r) {
207 case MAIL_NO_ERROR_NON_AUTHENTICATED:
208 case MAIL_NO_ERROR_AUTHENTICATED:
209 case MAIL_NO_ERROR:
210 break;
211 default:
212 res = r;
213 goto err;
214 }
215
216 r = mailstorage_generic_auth(session, r,
217 imap_storage->imap_connection_type,
218 imap_storage->imap_login,
219 imap_storage->imap_password);
220 if (r != MAIL_NO_ERROR) {
221 res = r;
222 goto free;
223 }
224
225 * result = session;
226
227 return MAIL_NO_ERROR;
228
229 free:
230 mailsession_free(session);
231 err:
232 return res;
233}
234
235static int imap_mailstorage_connect(struct mailstorage * storage)
236{
237 mailsession * session;
238 int r;
239 int res;
240
241 r = imap_connect(storage, &session);
242 if (r != MAIL_NO_ERROR) {
243 res = r;
244 goto err;
245 }
246
247 r = mailsession_select_folder(session, "INBOX");
248 if (r != MAIL_NO_ERROR) {
249 mailsession_logout(session);
250 res = r;
251 goto err;
252 }
253
254 storage->sto_session = session;
255 storage->sto_driver = &imap_mailstorage_driver;
256
257 return MAIL_NO_ERROR;
258
259 err:
260 return res;
261}
262
263static int
264imap_mailstorage_get_folder_session(struct mailstorage * storage,
265 char * pathname, mailsession ** result)
266{
267 mailsession * session;
268 int r;
269 int res;
270
271 if (strcasecmp(pathname, "INBOX") == 0) {
272 session = storage->sto_session;
273 }
274 else {
275 r = imap_connect(storage, &session);
276 if (r != MAIL_NO_ERROR) {
277 res = r;
278 goto err;
279 }
280
281 r = mailsession_select_folder(session, pathname);
282 if (r != MAIL_NO_ERROR) {
283 mailsession_logout(session);
284 res = r;
285 goto free;
286 }
287 }
288
289 * result = session;
290
291 return MAIL_NO_ERROR;
292
293 free:
294 mailsession_free(session);
295 err:
296 return res;
297}
diff --git a/kmicromail/libetpan/generic/imapstorage.h b/kmicromail/libetpan/generic/imapstorage.h
new file mode 100644
index 0000000..ebc42b0
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imapstorage.h
@@ -0,0 +1,90 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef IMAPSTORAGE_H
37
38#define IMAPSTORAGE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/imapdriver_types.h>
45
46/*
47 imap_mailstorage_init is the constructor for a IMAP4rev1 storage
48
49 @param storage this is the storage to initialize.
50
51 @param servername this is the name of the IMAP4rev1 server
52
53 @param port is the port to connect to, on the server.
54 you give 0 to use the default port.
55
56 @param command the command used to connect to the server instead of
57 allowing normal TCP connections to be used.
58
59 @param connection_type is the type of socket layer to use.
60 The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
61 CONNECTION_TYPE_TRY_STARTTLS, CONNECTION_TYPE_TLS,
62 CONNECTION_TYPE_COMMAND, CONNECTION_TYPE_COMMAND_STARTTLS,
63 CONNECTION_TYPE_COMMAND_TRY_STARTTLS, CONNECTION_TYPE_COMMAND_TLS,.
64
65 @param auth_type is the authenticate mechanism to use.
66 The value can be IMAP_AUTH_TYPE_PLAIN.
67 Other values are not yet implemented.
68
69 @param login is the login of the IMAP4rev1 account.
70
71 @param password is the password of the IMAP4rev1 account.
72
73 @param cached if this value is != 0, a persistant cache will be
74 stored on local system.
75
76 @param cache_directory is the location of the cache
77*/
78
79int imap_mailstorage_init(struct mailstorage * storage,
80 char * imap_servername, uint16_t imap_port,
81 char * imap_command,
82 int imap_connection_type, int imap_auth_type,
83 char * imap_login, char * imap_password,
84 int imap_cached, char * imap_cache_directory);
85
86#ifdef __cplusplus
87}
88#endif
89
90#endif
diff --git a/kmicromail/libetpan/generic/imfcache.c b/kmicromail/libetpan/generic/imfcache.c
new file mode 100644
index 0000000..64983f4
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imfcache.c
@@ -0,0 +1,1429 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "imfcache.h"
37
38#include <stdlib.h>
39#include <string.h>
40
41static int mailimf_cache_field_write(MMAPString * mmapstr, size_t * index,
42 struct mailimf_field * field);
43static int mailimf_cache_orig_date_write(MMAPString * mmapstr, size_t * index,
44 struct mailimf_orig_date * date);
45static int mailimf_cache_date_time_write(MMAPString * mmapstr, size_t * index,
46 struct mailimf_date_time * date_time);
47static int mailimf_cache_from_write(MMAPString * mmapstr, size_t * index,
48 struct mailimf_from * from);
49static int mailimf_cache_sender_write(MMAPString * mmapstr, size_t * index,
50 struct mailimf_sender * sender);
51static int mailimf_cache_reply_to_write(MMAPString * mmapstr, size_t * index,
52 struct mailimf_reply_to * reply_to);
53static int mailimf_cache_to_write(MMAPString * mmapstr, size_t * index,
54 struct mailimf_to * to);
55static int mailimf_cache_cc_write(MMAPString * mmapstr, size_t * index,
56 struct mailimf_cc * to);
57static int mailimf_cache_bcc_write(MMAPString * mmapstr, size_t * index,
58 struct mailimf_bcc * to);
59static int mailimf_cache_message_id_write(MMAPString * mmapstr, size_t * index,
60 struct mailimf_message_id * message_id);
61static int mailimf_cache_msg_id_list_write(MMAPString * mmapstr, size_t * index,
62 clist * list);
63static int mailimf_cache_in_reply_to_write(MMAPString * mmapstr, size_t * index,
64 struct mailimf_in_reply_to *
65 in_reply_to);
66static int mailimf_cache_references_write(MMAPString * mmapstr, size_t * index,
67 struct mailimf_references * references);
68static int mailimf_cache_subject_write(MMAPString * mmapstr, size_t * index,
69 struct mailimf_subject * subject);
70static int mailimf_cache_address_list_write(MMAPString * mmapstr,
71 size_t * index,
72 struct mailimf_address_list *
73 addr_list);
74static int mailimf_cache_address_write(MMAPString * mmapstr, size_t * index,
75 struct mailimf_address * addr);
76static int mailimf_cache_group_write(MMAPString * mmapstr, size_t * index,
77 struct mailimf_group * group);
78static int mailimf_cache_mailbox_list_write(MMAPString * mmapstr,
79 size_t * index,
80 struct mailimf_mailbox_list * mb_list);
81static int mailimf_cache_mailbox_write(MMAPString * mmapstr, size_t * index,
82 struct mailimf_mailbox * mb);
83
84
85static int mailimf_cache_field_read(MMAPString * mmapstr, size_t * index,
86 struct mailimf_field ** result);
87static int mailimf_cache_orig_date_read(MMAPString * mmapstr, size_t * index,
88 struct mailimf_orig_date ** result);
89static int mailimf_cache_date_time_read(MMAPString * mmapstr, size_t * index,
90 struct mailimf_date_time ** result);
91static int mailimf_cache_from_read(MMAPString * mmapstr, size_t * index,
92 struct mailimf_from ** result);
93static int mailimf_cache_sender_read(MMAPString * mmapstr, size_t * index,
94 struct mailimf_sender ** result);
95static int mailimf_cache_reply_to_read(MMAPString * mmapstr, size_t * index,
96 struct mailimf_reply_to ** result);
97static int mailimf_cache_to_read(MMAPString * mmapstr, size_t * index,
98 struct mailimf_to ** result);
99static int mailimf_cache_cc_read(MMAPString * mmapstr, size_t * index,
100 struct mailimf_cc ** result);
101static int mailimf_cache_bcc_read(MMAPString * mmapstr, size_t * index,
102 struct mailimf_bcc ** result);
103static int mailimf_cache_message_id_read(MMAPString * mmapstr, size_t * index,
104 struct mailimf_message_id ** result);
105static int mailimf_cache_msg_id_list_read(MMAPString * mmapstr, size_t * index,
106 clist ** result);
107static int
108mailimf_cache_in_reply_to_read(MMAPString * mmapstr, size_t * index,
109 struct mailimf_in_reply_to ** result);
110
111static int mailimf_cache_references_read(MMAPString * mmapstr, size_t * index,
112 struct mailimf_references ** result);
113static int mailimf_cache_subject_read(MMAPString * mmapstr, size_t * index,
114 struct mailimf_subject ** result);
115static int mailimf_cache_address_list_read(MMAPString * mmapstr, size_t * index,
116 struct mailimf_address_list ** result);
117static int mailimf_cache_address_read(MMAPString * mmapstr, size_t * index,
118 struct mailimf_address ** result);
119static int mailimf_cache_group_read(MMAPString * mmapstr, size_t * index,
120 struct mailimf_group ** result);
121static int
122mailimf_cache_mailbox_list_read(MMAPString * mmapstr, size_t * index,
123 struct mailimf_mailbox_list ** result);
124static int mailimf_cache_mailbox_read(MMAPString * mmapstr, size_t * index,
125 struct mailimf_mailbox ** result);
126
127enum {
128 CACHE_NULL_POINTER = 0,
129 CACHE_NOT_NULL = 1,
130};
131
132int mail_serialize_clear(MMAPString * mmapstr, size_t * index)
133{
134 if (mmap_string_set_size(mmapstr, 0) == NULL)
135 return MAIL_ERROR_MEMORY;
136
137 * index = 0;
138
139 return MAIL_NO_ERROR;
140}
141
142int mail_serialize_write(MMAPString * mmapstr, size_t * index,
143 char * buf, size_t size)
144{
145 if (mmap_string_append_len(mmapstr, buf, size) == NULL)
146 return MAIL_ERROR_MEMORY;
147
148 * index = * index + size;
149
150 return MAIL_NO_ERROR;
151}
152
153int mail_serialize_read(MMAPString * mmapstr, size_t * index,
154 char * buf, size_t size)
155{
156 size_t cur_token;
157
158 cur_token = * index;
159
160 if (cur_token + size > mmapstr->len)
161 return MAIL_ERROR_STREAM;
162
163 memcpy(buf, mmapstr->str + cur_token, size);
164 * index = cur_token + size;
165
166 return MAIL_NO_ERROR;
167}
168
169int mailimf_cache_int_write(MMAPString * mmapstr, size_t * index,
170 uint32_t value)
171{
172 unsigned char ch;
173 int r;
174 int i;
175
176 for(i = 0 ; i < 4 ; i ++) {
177 ch = value % 256;
178
179 r = mail_serialize_write(mmapstr, index, &ch, 1);
180 if (r != MAIL_NO_ERROR)
181 return r;
182 value /= 256;
183 }
184
185 return MAIL_NO_ERROR;
186}
187
188int mailimf_cache_int_read(MMAPString * mmapstr, size_t * index,
189 uint32_t * result)
190{
191 unsigned char ch;
192 uint32_t value;
193 int i;
194 int r;
195
196 value = 0;
197 for(i = 0 ; i < 4 ; i ++) {
198 r = mail_serialize_read(mmapstr, index, &ch, 1);
199 if (r != MAIL_NO_ERROR)
200 return r;
201 value = value | ch << (i << 3);
202 }
203
204 * result = value;
205
206 return MAIL_NO_ERROR;
207}
208
209
210int mailimf_cache_string_write(MMAPString * mmapstr, size_t * index,
211 char * str, size_t length)
212{
213 int r;
214
215 if (str == NULL) {
216 r = mailimf_cache_int_write(mmapstr, index, CACHE_NULL_POINTER);
217 if (r != MAIL_NO_ERROR)
218 return r;
219 }
220 else {
221 r = mailimf_cache_int_write(mmapstr, index, CACHE_NOT_NULL);
222 if (r != MAIL_NO_ERROR)
223 return r;
224
225 r = mailimf_cache_int_write(mmapstr, index, length);
226 if (r != MAIL_NO_ERROR)
227 return r;
228
229 if (length != 0) {
230 r = mail_serialize_write(mmapstr, index, str, length);
231 if (r != MAIL_NO_ERROR)
232 return MAIL_ERROR_FILE;
233 }
234 }
235
236 return MAIL_NO_ERROR;
237}
238
239int mailimf_cache_string_read(MMAPString * mmapstr, size_t * index,
240 char ** result)
241{
242 int r;
243 uint32_t length;
244 char * str;
245 uint32_t type;
246
247 r = mailimf_cache_int_read(mmapstr, index, &type);
248 if (r != MAIL_NO_ERROR)
249 return r;
250
251 if (type == CACHE_NULL_POINTER) {
252 str = NULL;
253 }
254 else {
255 r = mailimf_cache_int_read(mmapstr, index, &length);
256 if (r != MAIL_NO_ERROR)
257 return r;
258
259 str = malloc(length + 1);
260 if (str == NULL)
261 return MAIL_ERROR_MEMORY;
262
263 r = mail_serialize_read(mmapstr, index, str, length);
264 if (r != MAIL_NO_ERROR)
265 return MAIL_ERROR_FILE;
266
267 str[length] = 0;
268 }
269
270 * result = str;
271
272 return MAIL_NO_ERROR;
273}
274
275int mailimf_cache_fields_write(MMAPString * mmapstr, size_t * index,
276 struct mailimf_fields * fields)
277{
278 clistiter * cur;
279 int r;
280
281 r = mailimf_cache_int_write(mmapstr, index,
282 clist_count(fields->fld_list));
283 if (r != MAIL_NO_ERROR)
284 return r;
285
286 for(cur = clist_begin(fields->fld_list) ; cur != NULL ;
287 cur = clist_next(cur)) {
288 r = mailimf_cache_field_write(mmapstr, index, clist_content(cur));
289 if (r != MAIL_NO_ERROR)
290 return r;
291 }
292
293 return MAIL_NO_ERROR;
294}
295
296int mailimf_cache_fields_read(MMAPString * mmapstr, size_t * index,
297 struct mailimf_fields ** result)
298{
299 clist * list;
300 int r;
301 uint32_t count;
302 uint32_t i;
303 struct mailimf_fields * fields;
304 int res;
305
306 r = mailimf_cache_int_read(mmapstr, index, &count);
307 if (r != MAIL_NO_ERROR) {
308 res = r;
309 goto err;
310 }
311
312 list = clist_new();
313 if (list == NULL) {
314 res = MAIL_ERROR_MEMORY;
315 goto err;
316 }
317
318 for(i = 0 ; i < count ; i++) {
319 struct mailimf_field * field;
320
321 r = mailimf_cache_field_read(mmapstr, index, &field);
322 if (r != MAIL_NO_ERROR) {
323 res = r;
324 goto free_list;
325 }
326
327 r = clist_append(list, field);
328 if (r < 0) {
329 mailimf_field_free(field);
330 res = MAIL_ERROR_MEMORY;
331 goto free_list;
332 }
333 }
334
335 fields = mailimf_fields_new(list);
336 if (fields == NULL) {
337 res = MAIL_ERROR_MEMORY;
338 goto free_list;
339 }
340
341 * result = fields;
342
343 return MAIL_NO_ERROR;
344
345 free_list:
346 clist_foreach(list, (clist_func) mailimf_field_free, NULL);
347 clist_free(list);
348 err:
349 return res;
350}
351
352
353static int mailimf_cache_field_write(MMAPString * mmapstr, size_t * index,
354 struct mailimf_field * field)
355{
356 int r;
357
358 r = mailimf_cache_int_write(mmapstr, index, field->fld_type);
359 if (r != MAIL_NO_ERROR)
360 return r;
361
362 switch (field->fld_type) {
363 case MAILIMF_FIELD_ORIG_DATE:
364 r = mailimf_cache_orig_date_write(mmapstr, index,
365 field->fld_data.fld_orig_date);
366 break;
367 case MAILIMF_FIELD_FROM:
368 r = mailimf_cache_from_write(mmapstr, index,
369 field->fld_data.fld_from);
370 break;
371 case MAILIMF_FIELD_SENDER:
372 r = mailimf_cache_sender_write(mmapstr, index,
373 field->fld_data.fld_sender);
374 break;
375 case MAILIMF_FIELD_REPLY_TO:
376 r = mailimf_cache_reply_to_write(mmapstr, index,
377 field->fld_data.fld_reply_to);
378 break;
379 case MAILIMF_FIELD_TO:
380 r = mailimf_cache_to_write(mmapstr, index,
381 field->fld_data.fld_to);
382 break;
383 case MAILIMF_FIELD_CC:
384 r = mailimf_cache_cc_write(mmapstr, index,
385 field->fld_data.fld_cc);
386 break;
387 case MAILIMF_FIELD_BCC:
388 r = mailimf_cache_bcc_write(mmapstr, index,
389 field->fld_data.fld_bcc);
390 break;
391 case MAILIMF_FIELD_MESSAGE_ID:
392 r = mailimf_cache_message_id_write(mmapstr, index,
393 field->fld_data.fld_message_id);
394 break;
395 case MAILIMF_FIELD_IN_REPLY_TO:
396 r = mailimf_cache_in_reply_to_write(mmapstr, index,
397 field->fld_data.fld_in_reply_to);
398 break;
399 case MAILIMF_FIELD_REFERENCES:
400 r = mailimf_cache_references_write(mmapstr, index,
401 field->fld_data.fld_references);
402 break;
403 case MAILIMF_FIELD_SUBJECT:
404 r = mailimf_cache_subject_write(mmapstr, index,
405 field->fld_data.fld_subject);
406 break;
407 default:
408 r = 0;
409 break;
410 }
411
412 if (r != MAIL_NO_ERROR)
413 return r;
414
415 return MAIL_NO_ERROR;
416}
417
418
419static int mailimf_cache_field_read(MMAPString * mmapstr, size_t * index,
420 struct mailimf_field ** result)
421{
422 int r;
423 uint32_t type;
424 struct mailimf_orig_date * orig_date;
425 struct mailimf_from * from;
426 struct mailimf_sender * sender;
427 struct mailimf_to * to;
428 struct mailimf_reply_to * reply_to;
429 struct mailimf_cc * cc;
430 struct mailimf_bcc * bcc;
431 struct mailimf_message_id * message_id;
432 struct mailimf_in_reply_to * in_reply_to;
433 struct mailimf_references * references;
434 struct mailimf_subject * subject;
435 struct mailimf_field * field;
436 int res;
437
438 orig_date = NULL;
439 from = NULL;
440 sender = NULL;
441 to = NULL;
442 reply_to = NULL;
443 cc = NULL;
444 bcc = NULL;
445 message_id = NULL;
446 in_reply_to = NULL;
447 references = NULL;
448 subject = NULL;
449 field = NULL;
450
451 r = mailimf_cache_int_read(mmapstr, index, &type);
452 if (r != MAIL_NO_ERROR) {
453 res = r;
454 goto err;
455 }
456
457 switch (type) {
458 case MAILIMF_FIELD_ORIG_DATE:
459 r = mailimf_cache_orig_date_read(mmapstr, index, &orig_date);
460 break;
461 case MAILIMF_FIELD_FROM:
462 r = mailimf_cache_from_read(mmapstr, index, &from);
463 break;
464 case MAILIMF_FIELD_SENDER:
465 r = mailimf_cache_sender_read(mmapstr, index, &sender);
466 break;
467 case MAILIMF_FIELD_REPLY_TO:
468 r = mailimf_cache_reply_to_read(mmapstr, index, &reply_to);
469 break;
470 case MAILIMF_FIELD_TO:
471 r = mailimf_cache_to_read(mmapstr, index, &to);
472 break;
473 case MAILIMF_FIELD_CC:
474 r = mailimf_cache_cc_read(mmapstr, index, &cc);
475 break;
476 case MAILIMF_FIELD_BCC:
477 r = mailimf_cache_bcc_read(mmapstr, index, &bcc);
478 break;
479 case MAILIMF_FIELD_MESSAGE_ID:
480 r = mailimf_cache_message_id_read(mmapstr, index, &message_id);
481 break;
482 case MAILIMF_FIELD_IN_REPLY_TO:
483 r = mailimf_cache_in_reply_to_read(mmapstr, index, &in_reply_to);
484 break;
485 case MAILIMF_FIELD_REFERENCES:
486 r = mailimf_cache_references_read(mmapstr, index, &references);
487 break;
488 case MAILIMF_FIELD_SUBJECT:
489 r = mailimf_cache_subject_read(mmapstr, index, &subject);
490 break;
491 default:
492 r = MAIL_ERROR_INVAL;
493 break;
494 }
495
496 if (r != MAIL_NO_ERROR) {
497 res = r;
498 goto free;
499 }
500
501 field = mailimf_field_new(type, NULL, NULL, NULL, NULL, NULL,
502 NULL, NULL, NULL, orig_date, from, sender, reply_to,
503 to, cc, bcc, message_id,
504 in_reply_to, references,
505 subject, NULL, NULL, NULL);
506 if (field == NULL) {
507 res = MAIL_ERROR_MEMORY;
508 goto free;
509 }
510
511 * result = field;
512
513 return MAIL_NO_ERROR;
514
515 free:
516 if (orig_date != NULL)
517 mailimf_orig_date_free(orig_date);
518 if (from != NULL)
519 mailimf_from_free(from);
520 if (sender != NULL)
521 mailimf_sender_free(sender);
522 if (reply_to != NULL)
523 mailimf_reply_to_free(reply_to);
524 if (to != NULL)
525 mailimf_to_free(to);
526 if (cc != NULL)
527 mailimf_cc_free(cc);
528 if (bcc != NULL)
529 mailimf_bcc_free(bcc);
530 if (message_id != NULL)
531 mailimf_message_id_free(message_id);
532 if (in_reply_to != NULL)
533 mailimf_in_reply_to_free(in_reply_to);
534 if (references != NULL)
535 mailimf_references_free(references);
536 if (subject != NULL)
537 mailimf_subject_free(subject);
538 err:
539 return res;
540}
541
542static int mailimf_cache_orig_date_write(MMAPString * mmapstr, size_t * index,
543 struct mailimf_orig_date * date)
544{
545 return mailimf_cache_date_time_write(mmapstr, index, date->dt_date_time);
546}
547
548static int mailimf_cache_orig_date_read(MMAPString * mmapstr, size_t * index,
549 struct mailimf_orig_date ** result)
550{
551 int r;
552 struct mailimf_date_time * date_time;
553 struct mailimf_orig_date * orig_date;
554
555 r = mailimf_cache_date_time_read(mmapstr, index, &date_time);
556 if (r != MAIL_NO_ERROR)
557 return r;
558
559 orig_date = mailimf_orig_date_new(date_time);
560 if (orig_date == NULL) {
561 mailimf_date_time_free(date_time);
562 return MAIL_ERROR_MEMORY;
563 }
564
565 * result = orig_date;
566
567 return MAIL_NO_ERROR;
568}
569
570static int mailimf_cache_date_time_write(MMAPString * mmapstr, size_t * index,
571 struct mailimf_date_time * date_time)
572{
573 int r;
574
575 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_day);
576 if (r != MAIL_NO_ERROR)
577 return r;
578
579 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_month);
580 if (r != MAIL_NO_ERROR)
581 return r;
582
583 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_year);
584 if (r != MAIL_NO_ERROR)
585 return r;
586
587 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_hour);
588 if (r != MAIL_NO_ERROR)
589 return r;
590
591 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_min);
592 if (r != MAIL_NO_ERROR)
593 return r;
594
595 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_sec);
596 if (r != MAIL_NO_ERROR)
597 return r;
598
599 r = mailimf_cache_int_write(mmapstr, index, date_time->dt_zone);
600 if (r != MAIL_NO_ERROR)
601 return r;
602
603 return MAIL_NO_ERROR;
604}
605
606static int mailimf_cache_date_time_read(MMAPString * mmapstr, size_t * index,
607 struct mailimf_date_time ** result)
608{
609 int r;
610 uint32_t day;
611 uint32_t month;
612 uint32_t year;
613 uint32_t hour;
614 uint32_t min;
615 uint32_t sec;
616 uint32_t zone;
617 struct mailimf_date_time * date_time;
618
619 r = mailimf_cache_int_read(mmapstr, index, &day);
620 if (r != MAIL_NO_ERROR)
621 return r;
622
623 r = mailimf_cache_int_read(mmapstr, index, &month);
624 if (r != MAIL_NO_ERROR)
625 return r;
626
627 r = mailimf_cache_int_read(mmapstr, index, &year);
628 if (r != MAIL_NO_ERROR)
629 return r;
630
631 r = mailimf_cache_int_read(mmapstr, index, &hour);
632 if (r != MAIL_NO_ERROR)
633 return r;
634
635 r = mailimf_cache_int_read(mmapstr, index, &min);
636 if (r != MAIL_NO_ERROR)
637 return r;
638
639 r = mailimf_cache_int_read(mmapstr, index, &sec);
640 if (r != MAIL_NO_ERROR)
641 return r;
642
643 r = mailimf_cache_int_read(mmapstr, index, &zone);
644 if (r != MAIL_NO_ERROR)
645 return r;
646
647 date_time = mailimf_date_time_new(day, month, year, hour, min, sec, zone);
648 if (date_time == NULL)
649 return MAIL_ERROR_MEMORY;
650
651 * result = date_time;
652
653 return MAIL_NO_ERROR;
654
655}
656
657
658static int mailimf_cache_from_write(MMAPString * mmapstr, size_t * index,
659 struct mailimf_from * from)
660{
661 return mailimf_cache_mailbox_list_write(mmapstr, index, from->frm_mb_list);
662}
663
664static int mailimf_cache_from_read(MMAPString * mmapstr, size_t * index,
665 struct mailimf_from ** result)
666{
667 struct mailimf_mailbox_list * mb_list;
668 struct mailimf_from * from;
669 int r;
670
671 r = mailimf_cache_mailbox_list_read(mmapstr, index, &mb_list);
672 if (r != MAIL_NO_ERROR)
673 return r;
674
675 from = mailimf_from_new(mb_list);
676 if (from == NULL) {
677 mailimf_mailbox_list_free(mb_list);
678 return MAIL_ERROR_MEMORY;
679 }
680
681 * result = from;
682
683 return MAIL_NO_ERROR;
684}
685
686static int mailimf_cache_sender_write(MMAPString * mmapstr, size_t * index,
687 struct mailimf_sender * sender)
688{
689 return mailimf_cache_mailbox_write(mmapstr, index, sender->snd_mb);
690}
691
692static int mailimf_cache_sender_read(MMAPString * mmapstr, size_t * index,
693 struct mailimf_sender ** result)
694{
695 int r;
696 struct mailimf_mailbox * mb;
697 struct mailimf_sender * sender;
698
699 r = mailimf_cache_mailbox_read(mmapstr, index, &mb);
700 if (r != MAIL_NO_ERROR)
701 return r;
702
703 sender = mailimf_sender_new(mb);
704 if (sender == NULL) {
705 mailimf_mailbox_free(mb);
706 return MAIL_ERROR_MEMORY;
707 }
708
709 * result = sender;
710
711 return MAIL_NO_ERROR;
712}
713
714static int mailimf_cache_reply_to_write(MMAPString * mmapstr, size_t * index,
715 struct mailimf_reply_to * reply_to)
716{
717 return mailimf_cache_address_list_write(mmapstr, index,
718 reply_to->rt_addr_list);
719}
720
721static int mailimf_cache_reply_to_read(MMAPString * mmapstr, size_t * index,
722 struct mailimf_reply_to ** result)
723{
724 int r;
725 struct mailimf_address_list * addr_list;
726 struct mailimf_reply_to * reply_to;
727
728 r = mailimf_cache_address_list_read(mmapstr, index, &addr_list);
729 if (r != MAIL_NO_ERROR)
730 return r;
731
732 reply_to = mailimf_reply_to_new(addr_list);
733 if (reply_to == NULL) {
734 mailimf_address_list_free(addr_list);
735 return MAIL_ERROR_MEMORY;
736 }
737
738 * result = reply_to;
739
740 return MAIL_NO_ERROR;
741}
742
743static int mailimf_cache_to_write(MMAPString * mmapstr, size_t * index,
744 struct mailimf_to * to)
745{
746 return mailimf_cache_address_list_write(mmapstr, index, to->to_addr_list);
747}
748
749static int mailimf_cache_to_read(MMAPString * mmapstr, size_t * index,
750 struct mailimf_to ** result)
751{
752 int r;
753 struct mailimf_address_list * addr_list;
754 struct mailimf_to * to;
755
756 r = mailimf_cache_address_list_read(mmapstr, index, &addr_list);
757 if (r != MAIL_NO_ERROR)
758 return r;
759
760 to = mailimf_to_new(addr_list);
761 if (to == NULL) {
762 mailimf_address_list_free(addr_list);
763 return MAIL_ERROR_MEMORY;
764 }
765
766 * result = to;
767
768 return MAIL_NO_ERROR;
769}
770
771static int mailimf_cache_cc_write(MMAPString * mmapstr, size_t * index,
772 struct mailimf_cc * cc)
773{
774 return mailimf_cache_address_list_write(mmapstr, index, cc->cc_addr_list);
775}
776
777static int mailimf_cache_cc_read(MMAPString * mmapstr, size_t * index,
778 struct mailimf_cc ** result)
779{
780 int r;
781 struct mailimf_address_list * addr_list;
782 struct mailimf_cc * cc;
783
784 r = mailimf_cache_address_list_read(mmapstr, index, &addr_list);
785 if (r != MAIL_NO_ERROR)
786 return r;
787
788 cc = mailimf_cc_new(addr_list);
789 if (cc == NULL) {
790 mailimf_address_list_free(addr_list);
791 return MAIL_ERROR_MEMORY;
792 }
793
794 * result = cc;
795
796 return MAIL_NO_ERROR;
797}
798
799static int mailimf_cache_bcc_write(MMAPString * mmapstr, size_t * index,
800 struct mailimf_bcc * bcc)
801{
802 return mailimf_cache_address_list_write(mmapstr, index, bcc->bcc_addr_list);
803}
804
805static int mailimf_cache_bcc_read(MMAPString * mmapstr, size_t * index,
806 struct mailimf_bcc ** result)
807{
808 int r;
809 struct mailimf_address_list * addr_list;
810 struct mailimf_bcc * bcc;
811
812 r = mailimf_cache_address_list_read(mmapstr, index, &addr_list);
813 if (r != MAIL_NO_ERROR)
814 return r;
815
816 bcc = mailimf_bcc_new(addr_list);
817 if (bcc == NULL) {
818 mailimf_address_list_free(addr_list);
819 return MAIL_ERROR_MEMORY;
820 }
821
822 * result = bcc;
823
824 return MAIL_NO_ERROR;
825}
826
827static int
828mailimf_cache_message_id_write(MMAPString * mmapstr, size_t * index,
829 struct mailimf_message_id * message_id)
830{
831 return mailimf_cache_string_write(mmapstr, index,
832 message_id->mid_value, strlen(message_id->mid_value));
833}
834
835static int mailimf_cache_message_id_read(MMAPString * mmapstr, size_t * index,
836 struct mailimf_message_id ** result)
837{
838 struct mailimf_message_id * message_id;
839 char * str;
840 int r;
841
842 r = mailimf_cache_string_read(mmapstr, index, &str);
843 if (r != MAIL_NO_ERROR)
844 return r;
845
846 message_id = mailimf_message_id_new(str);
847 if (message_id == NULL) {
848 free(str);
849 return MAIL_ERROR_MEMORY;
850 }
851
852 * result = message_id;
853
854 return MAIL_NO_ERROR;
855}
856
857static int
858mailimf_cache_msg_id_list_write(MMAPString * mmapstr, size_t * index,
859 clist * list)
860{
861 clistiter * cur;
862 int r;
863
864 r = mailimf_cache_int_write(mmapstr, index, clist_count(list));
865 if (r != MAIL_NO_ERROR)
866 return r;
867
868 for(cur = clist_begin(list) ; cur != NULL ; cur = clist_next(cur)) {
869 char * msgid;
870
871 msgid = clist_content(cur);
872
873 r = mailimf_cache_string_write(mmapstr, index, msgid, strlen(msgid));
874 if (r != MAIL_NO_ERROR)
875 return r;
876 }
877
878 return MAIL_NO_ERROR;
879}
880
881static int mailimf_cache_msg_id_list_read(MMAPString * mmapstr, size_t * index,
882 clist ** result)
883{
884 clist * list;
885 int r;
886 uint32_t count;
887 uint32_t i;
888 int res;
889
890 r = mailimf_cache_int_read(mmapstr, index, &count);
891 if (r != MAIL_NO_ERROR) {
892 res = r;
893 goto err;
894 }
895
896 list = clist_new();
897 if (list == NULL) {
898 res = MAIL_ERROR_MEMORY;
899 goto err;
900 }
901
902 for(i = 0 ; i < count ; i++) {
903 char * msgid;
904
905 r = mailimf_cache_string_read(mmapstr, index, &msgid);
906 if (r != MAIL_NO_ERROR) {
907 res = r;
908 goto err;
909 }
910
911 r = clist_append(list, msgid);
912 if (r < 0) {
913 free(msgid);
914 res = MAIL_ERROR_MEMORY;
915 goto free_list;
916 }
917 }
918
919 * result = list;
920
921 return MAIL_NO_ERROR;
922
923 free_list:
924 clist_foreach(list, (clist_func) free, NULL);
925 clist_free(list);
926 err:
927 return res;
928}
929
930static int
931mailimf_cache_in_reply_to_write(MMAPString * mmapstr, size_t * index,
932 struct mailimf_in_reply_to * in_reply_to)
933{
934 return mailimf_cache_msg_id_list_write(mmapstr, index,
935 in_reply_to->mid_list);
936}
937
938static int mailimf_cache_in_reply_to_read(MMAPString * mmapstr, size_t * index,
939 struct mailimf_in_reply_to ** result)
940{
941 int r;
942 clist * msg_id_list;
943 struct mailimf_in_reply_to * in_reply_to;
944
945 r = mailimf_cache_msg_id_list_read(mmapstr, index, &msg_id_list);
946 if (r != MAIL_NO_ERROR)
947 return r;
948
949 in_reply_to = mailimf_in_reply_to_new(msg_id_list);
950 if (in_reply_to == NULL) {
951 clist_foreach(msg_id_list, (clist_func) free, NULL);
952 clist_free(msg_id_list);
953 return MAIL_ERROR_MEMORY;
954 }
955
956 * result = in_reply_to;
957
958 return MAIL_NO_ERROR;
959}
960
961static int mailimf_cache_references_write(MMAPString * mmapstr, size_t * index,
962 struct mailimf_references * references)
963{
964 return mailimf_cache_msg_id_list_write(mmapstr, index,
965 references->mid_list);
966}
967
968static int mailimf_cache_references_read(MMAPString * mmapstr, size_t * index,
969 struct mailimf_references ** result)
970{
971 int r;
972 clist * msg_id_list;
973 struct mailimf_references * references;
974
975 r = mailimf_cache_msg_id_list_read(mmapstr, index, &msg_id_list);
976 if (r != MAIL_NO_ERROR)
977 return r;
978
979 references = mailimf_references_new(msg_id_list);
980 if (references == NULL) {
981 clist_foreach(msg_id_list, (clist_func) free, NULL);
982 clist_free(msg_id_list);
983 return MAIL_ERROR_MEMORY;
984 }
985
986 * result = references;
987
988 return MAIL_NO_ERROR;
989}
990
991
992static int mailimf_cache_subject_write(MMAPString * mmapstr, size_t * index,
993 struct mailimf_subject * subject)
994{
995 return mailimf_cache_string_write(mmapstr, index,
996 subject->sbj_value, strlen(subject->sbj_value));
997}
998
999static int mailimf_cache_subject_read(MMAPString * mmapstr, size_t * index,
1000 struct mailimf_subject ** result)
1001{
1002 char * str;
1003 struct mailimf_subject * subject;
1004 int r;
1005
1006 r = mailimf_cache_string_read(mmapstr, index, &str);
1007 if (r != MAIL_NO_ERROR)
1008 return r;
1009
1010 if (str == NULL) {
1011 str = strdup("");
1012 if (str == NULL)
1013 return MAIL_ERROR_MEMORY;
1014 }
1015
1016 subject = mailimf_subject_new(str);
1017 if (subject == NULL) {
1018 free(str);
1019 return MAIL_ERROR_MEMORY;
1020 }
1021
1022 * result = subject;
1023
1024 return MAIL_NO_ERROR;
1025}
1026
1027
1028static int
1029mailimf_cache_address_list_write(MMAPString * mmapstr, size_t * index,
1030 struct mailimf_address_list * addr_list)
1031{
1032 clistiter * cur;
1033 int r;
1034
1035 if (addr_list == NULL) {
1036 r = mailimf_cache_int_write(mmapstr, index, CACHE_NULL_POINTER);
1037 if (r != MAIL_NO_ERROR)
1038 return r;
1039 }
1040 else {
1041 r = mailimf_cache_int_write(mmapstr, index, CACHE_NOT_NULL);
1042 if (r != MAIL_NO_ERROR)
1043 return r;
1044
1045 r = mailimf_cache_int_write(mmapstr, index,
1046 clist_count(addr_list->ad_list));
1047 if (r != MAIL_NO_ERROR)
1048 return r;
1049
1050 for(cur = clist_begin(addr_list->ad_list) ; cur != NULL ;
1051 cur = clist_next(cur)) {
1052 struct mailimf_address * addr;
1053
1054 addr = clist_content(cur);
1055
1056 r = mailimf_cache_address_write(mmapstr, index, addr);
1057 if (r != MAIL_NO_ERROR)
1058 return r;
1059 }
1060 }
1061
1062 return MAIL_NO_ERROR;
1063}
1064
1065static int
1066mailimf_cache_address_list_read(MMAPString * mmapstr, size_t * index,
1067 struct mailimf_address_list ** result)
1068{
1069 struct mailimf_address_list * addr_list;
1070 uint32_t count;
1071 uint32_t i;
1072 int r;
1073 clist * list;
1074 int res;
1075 uint32_t type;
1076
1077 r = mailimf_cache_int_read(mmapstr, index, &type);
1078 if (r != MAIL_NO_ERROR) {
1079 res = r;
1080 goto err;
1081 }
1082
1083 if (type == CACHE_NULL_POINTER) {
1084 * result = NULL;
1085 return MAIL_NO_ERROR;
1086 }
1087
1088 r = mailimf_cache_int_read(mmapstr, index, &count);
1089 if (r != MAIL_NO_ERROR) {
1090 res = r;
1091 goto err;
1092 }
1093
1094 list = clist_new();
1095 if (list == NULL) {
1096 res = MAIL_ERROR_MEMORY;
1097 goto err;
1098 }
1099
1100 for(i = 0 ; i < count ; i++) {
1101 struct mailimf_address * addr;
1102
1103 r = mailimf_cache_address_read(mmapstr, index, &addr);
1104 if (r != MAIL_NO_ERROR) {
1105 res = r;
1106 goto free_list;
1107 }
1108
1109 r = clist_append(list, addr);
1110 if (r < 0) {
1111 mailimf_address_free(addr);
1112 res = MAIL_ERROR_MEMORY;
1113 goto free_list;
1114 }
1115 }
1116
1117 addr_list = mailimf_address_list_new(list);
1118 if (addr_list == NULL) {
1119 res = MAIL_ERROR_MEMORY;
1120 goto free_list;
1121 }
1122
1123 * result = addr_list;
1124
1125 return MAIL_NO_ERROR;
1126
1127 free_list:
1128 clist_foreach(list, (clist_func) mailimf_address_free, NULL);
1129 clist_free(list);
1130 err:
1131 return res;
1132}
1133
1134static int mailimf_cache_address_write(MMAPString * mmapstr, size_t * index,
1135 struct mailimf_address * addr)
1136{
1137 int r;
1138
1139 r = mailimf_cache_int_write(mmapstr, index, addr->ad_type);
1140 if (r != MAIL_NO_ERROR)
1141 return r;
1142
1143 switch(addr->ad_type) {
1144 case MAILIMF_ADDRESS_MAILBOX:
1145 r = mailimf_cache_mailbox_write(mmapstr, index, addr->ad_data.ad_mailbox);
1146 if (r != MAIL_NO_ERROR)
1147 return r;
1148
1149 break;
1150
1151 case MAILIMF_ADDRESS_GROUP:
1152 r = mailimf_cache_group_write(mmapstr, index, addr->ad_data.ad_group);
1153 if (r != MAIL_NO_ERROR)
1154 return r;
1155
1156 break;
1157 }
1158
1159 return MAIL_NO_ERROR;
1160}
1161
1162static int mailimf_cache_address_read(MMAPString * mmapstr, size_t * index,
1163 struct mailimf_address ** result)
1164{
1165 uint32_t type;
1166 int r;
1167 struct mailimf_mailbox * mailbox;
1168 struct mailimf_group * group;
1169 struct mailimf_address * addr;
1170
1171 r = mailimf_cache_int_read(mmapstr, index, &type);
1172 if (r != MAIL_NO_ERROR)
1173 return r;
1174
1175 mailbox = NULL;
1176 group = NULL;
1177
1178 switch (type) {
1179 case MAILIMF_ADDRESS_MAILBOX:
1180 r = mailimf_cache_mailbox_read(mmapstr, index, &mailbox);
1181 if (r != MAIL_NO_ERROR)
1182 return r;
1183
1184 break;
1185
1186 case MAILIMF_ADDRESS_GROUP:
1187 r = mailimf_cache_group_read(mmapstr, index, &group);
1188 if (r != MAIL_NO_ERROR)
1189 return r;
1190
1191 break;
1192 }
1193
1194 addr = mailimf_address_new(type, mailbox, group);
1195 if (addr == NULL)
1196 goto free;
1197
1198 * result = addr;
1199
1200 return MAIL_NO_ERROR;
1201
1202 free:
1203 if (mailbox != NULL)
1204 mailimf_mailbox_free(mailbox);
1205 if (group != NULL)
1206 mailimf_group_free(group);
1207 return MAIL_ERROR_MEMORY;
1208}
1209
1210static int mailimf_cache_group_write(MMAPString * mmapstr, size_t * index,
1211 struct mailimf_group * group)
1212{
1213 int r;
1214
1215 r = mailimf_cache_string_write(mmapstr, index, group->grp_display_name,
1216 strlen(group->grp_display_name));
1217 if (r != MAIL_NO_ERROR)
1218 return r;
1219
1220 r = mailimf_cache_mailbox_list_write(mmapstr, index, group->grp_mb_list);
1221 if (r != MAIL_NO_ERROR)
1222 return r;
1223
1224 return MAIL_NO_ERROR;
1225}
1226
1227static int mailimf_cache_group_read(MMAPString * mmapstr, size_t * index,
1228 struct mailimf_group ** result)
1229{
1230 int r;
1231 char * display_name;
1232 struct mailimf_mailbox_list * mb_list;
1233 struct mailimf_group * group;
1234 int res;
1235
1236 r = mailimf_cache_string_read(mmapstr, index, &display_name);
1237 if (r != MAIL_NO_ERROR) {
1238 res = r;
1239 goto err;
1240 }
1241
1242 r = mailimf_cache_mailbox_list_read(mmapstr, index, &mb_list);
1243 if (r != MAIL_NO_ERROR) {
1244 res = r;
1245 goto free_dsp_name;
1246 }
1247
1248 group = mailimf_group_new(display_name, mb_list);
1249 if (group == NULL) {
1250 res = MAIL_ERROR_MEMORY;
1251 goto free_mb_list;
1252 }
1253
1254 * result = group;
1255
1256 return MAIL_NO_ERROR;
1257
1258 free_mb_list:
1259 mailimf_mailbox_list_free(mb_list);
1260 free_dsp_name:
1261 free(display_name);
1262 err:
1263 return res;
1264}
1265
1266static int
1267mailimf_cache_mailbox_list_write(MMAPString * mmapstr, size_t * index,
1268 struct mailimf_mailbox_list * mb_list)
1269{
1270 clistiter * cur;
1271 int r;
1272
1273 if (mb_list == NULL) {
1274 r = mailimf_cache_int_write(mmapstr, index, CACHE_NULL_POINTER);
1275 if (r != MAIL_NO_ERROR)
1276 return r;
1277 }
1278 else {
1279 r = mailimf_cache_int_write(mmapstr, index, CACHE_NOT_NULL);
1280 if (r != MAIL_NO_ERROR)
1281 return r;
1282
1283 r = mailimf_cache_int_write(mmapstr, index,
1284 clist_count(mb_list->mb_list));
1285 if (r != MAIL_NO_ERROR)
1286 return r;
1287
1288 for(cur = clist_begin(mb_list->mb_list) ; cur != NULL ;
1289 cur = clist_next(cur)) {
1290 struct mailimf_mailbox * mb;
1291
1292 mb = clist_content(cur);
1293
1294 r = mailimf_cache_mailbox_write(mmapstr, index, mb);
1295 if (r != MAIL_NO_ERROR)
1296 return r;
1297 }
1298 }
1299
1300 return MAIL_NO_ERROR;
1301}
1302
1303static int
1304mailimf_cache_mailbox_list_read(MMAPString * mmapstr, size_t * index,
1305 struct mailimf_mailbox_list ** result)
1306{
1307 clist * list;
1308 int r;
1309 uint32_t count;
1310 uint32_t i;
1311 struct mailimf_mailbox_list * mb_list;
1312 int res;
1313 uint32_t type;
1314
1315 r = mailimf_cache_int_read(mmapstr, index, &type);
1316 if (r != MAIL_NO_ERROR) {
1317 res = r;
1318 goto err;
1319 }
1320
1321 if (type == CACHE_NULL_POINTER) {
1322 * result = NULL;
1323 return MAIL_NO_ERROR;
1324 }
1325
1326 r = mailimf_cache_int_read(mmapstr, index, &count);
1327 if (r != MAIL_NO_ERROR) {
1328 res = r;
1329 goto err;
1330 }
1331
1332 list = clist_new();
1333 if (list == NULL) {
1334 res = MAIL_ERROR_MEMORY;
1335 goto err;
1336 }
1337
1338 for(i = 0 ; i < count ; i++) {
1339 struct mailimf_mailbox * mb;
1340
1341 r = mailimf_cache_mailbox_read(mmapstr, index, &mb);
1342 if (r != MAIL_NO_ERROR) {
1343 res = r;
1344 goto free_list;
1345 }
1346
1347 r = clist_append(list, mb);
1348 if (r < 0) {
1349 mailimf_mailbox_free(mb);
1350 res = MAIL_ERROR_MEMORY;
1351 goto free_list;
1352 }
1353 }
1354
1355 mb_list = mailimf_mailbox_list_new(list);
1356 if (mb_list == NULL) {
1357 res = MAIL_ERROR_MEMORY;
1358 goto free_list;
1359 }
1360
1361 * result = mb_list;
1362
1363 return MAIL_NO_ERROR;
1364
1365 free_list:
1366 clist_foreach(list, (clist_func) mailimf_mailbox_free, NULL);
1367 clist_free(list);
1368 err:
1369 return res;
1370}
1371
1372static int mailimf_cache_mailbox_write(MMAPString * mmapstr, size_t * index,
1373 struct mailimf_mailbox * mb)
1374{
1375 int r;
1376
1377 if (mb->mb_display_name) {
1378 r = mailimf_cache_string_write(mmapstr, index,
1379 mb->mb_display_name, strlen(mb->mb_display_name));
1380 if (r != MAIL_NO_ERROR)
1381 return r;
1382 }
1383 else {
1384 r = mailimf_cache_string_write(mmapstr, index, NULL, 0);
1385 if (r != MAIL_NO_ERROR)
1386 return r;
1387 }
1388
1389 r = mailimf_cache_string_write(mmapstr, index,
1390 mb->mb_addr_spec, strlen(mb->mb_addr_spec));
1391 if (r != MAIL_NO_ERROR)
1392 return r;
1393
1394 return MAIL_NO_ERROR;
1395}
1396
1397static int mailimf_cache_mailbox_read(MMAPString * mmapstr, size_t * index,
1398 struct mailimf_mailbox ** result)
1399{
1400 int r;
1401 char * dsp_name;
1402 char * addr_spec;
1403 struct mailimf_mailbox * mb;
1404
1405 dsp_name = NULL;
1406
1407 r = mailimf_cache_string_read(mmapstr, index, &dsp_name);
1408 if (r != MAIL_NO_ERROR)
1409 return r;
1410
1411 r = mailimf_cache_string_read(mmapstr, index, &addr_spec);
1412 if (r != MAIL_NO_ERROR)
1413 goto free_dsp_name;
1414
1415 mb = mailimf_mailbox_new(dsp_name, addr_spec);
1416 if (mb == NULL)
1417 goto free_addr;
1418
1419 * result = mb;
1420
1421 return MAIL_NO_ERROR;
1422
1423 free_addr:
1424 free(addr_spec);
1425 free_dsp_name:
1426 if (dsp_name != NULL)
1427 free(dsp_name);
1428 return MAIL_ERROR_MEMORY;
1429}
diff --git a/kmicromail/libetpan/generic/imfcache.h b/kmicromail/libetpan/generic/imfcache.h
new file mode 100644
index 0000000..31c99c0
--- a/dev/null
+++ b/kmicromail/libetpan/generic/imfcache.h
@@ -0,0 +1,75 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef IMFCACHE_H
37
38#define IMFCACHE_H
39
40#include <stdio.h>
41#include "mailimf.h"
42#include "maildriver_types.h"
43#include "mmapstring.h"
44
45#ifdef __cplusplus
46extern "C" {
47#endif
48
49int mail_serialize_clear(MMAPString * mmapstr, size_t * index);
50
51int mail_serialize_write(MMAPString * mmapstr, size_t * index,
52 char * buf, size_t size);
53
54int mail_serialize_read(MMAPString * mmapstr, size_t * index,
55 char * buf, size_t size);
56
57int mailimf_cache_int_write(MMAPString * mmapstr, size_t * index,
58 uint32_t value);
59int mailimf_cache_string_write(MMAPString * mmapstr, size_t * index,
60 char * str, size_t length);
61int mailimf_cache_int_read(MMAPString * mmapstr, size_t * index,
62 uint32_t * result);
63int mailimf_cache_string_read(MMAPString * mmapstr, size_t * index,
64 char ** result);
65
66int mailimf_cache_fields_write(MMAPString * mmapstr, size_t * index,
67 struct mailimf_fields * fields);
68int mailimf_cache_fields_read(MMAPString * mmapstr, size_t * index,
69 struct mailimf_fields ** result);
70
71#ifdef __cplusplus
72}
73#endif
74
75#endif
diff --git a/kmicromail/libetpan/generic/libetpan.h b/kmicromail/libetpan/generic/libetpan.h
new file mode 100644
index 0000000..3b4a107
--- a/dev/null
+++ b/kmicromail/libetpan/generic/libetpan.h
@@ -0,0 +1,104 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef LIBETPAN_H
37
38#define LIBETPAN_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/libetpan_version.h>
45#include <libetpan/maildriver.h>
46#include <libetpan/mailmessage.h>
47#include <libetpan/mailstorage.h>
48#include <libetpan/mailthread.h>
49#include <libetpan/mailsmtp.h>
50#include <libetpan/charconv.h>
51
52/* mbox driver */
53#include <libetpan/mboxdriver.h>
54#include <libetpan/mboxdriver_message.h>
55#include <libetpan/mboxdriver_cached.h>
56#include <libetpan/mboxdriver_cached_message.h>
57#include <libetpan/mboxstorage.h>
58
59/* MH driver */
60#include <libetpan/mhdriver.h>
61#include <libetpan/mhdriver_message.h>
62#include <libetpan/mhdriver_cached.h>
63#include <libetpan/mhdriver_cached_message.h>
64#include <libetpan/mhstorage.h>
65
66/* IMAP4rev1 driver */
67#include <libetpan/imapdriver.h>
68#include <libetpan/imapdriver_message.h>
69#include <libetpan/imapdriver_cached.h>
70#include <libetpan/imapdriver_cached_message.h>
71#include <libetpan/imapstorage.h>
72
73/* POP3 driver */
74#include <libetpan/pop3driver.h>
75#include <libetpan/pop3driver_message.h>
76#include <libetpan/pop3driver_cached.h>
77#include <libetpan/pop3driver_cached_message.h>
78#include <libetpan/pop3storage.h>
79
80/* NNTP driver */
81#include <libetpan/nntpdriver.h>
82#include <libetpan/nntpdriver_message.h>
83#include <libetpan/nntpdriver_cached.h>
84#include <libetpan/nntpdriver_cached_message.h>
85#include <libetpan/nntpstorage.h>
86
87/* maildir driver */
88#include <libetpan/maildirdriver.h>
89#include <libetpan/maildirdriver_message.h>
90#include <libetpan/maildirdriver_cached.h>
91#include <libetpan/maildirdriver_cached_message.h>
92#include <libetpan/maildirstorage.h>
93
94/* message which content is given by a MIME structure */
95#include <libetpan/mime_message_driver.h>
96
97/* message which content given by a string */
98#include <libetpan/data_message_driver.h>
99
100#ifdef __cplusplus
101}
102#endif
103
104#endif
diff --git a/kmicromail/libetpan/generic/libetpan_version.c b/kmicromail/libetpan/generic/libetpan_version.c
new file mode 100644
index 0000000..d4ea6ec
--- a/dev/null
+++ b/kmicromail/libetpan/generic/libetpan_version.c
@@ -0,0 +1,18 @@
1#include "libetpan_version.h"
2
3#ifndef CONFIG_H
4#define CONFIG_H
5#include "config.h"
6#endif
7
8/* version of libEtPan! at runtime */
9
10int libetpan_get_version_major(void)
11{
12 return LIBETPAN_VERSION_MAJOR;
13}
14
15int libetpan_get_version_minor(void)
16{
17 return LIBETPAN_VERSION_MINOR;
18}
diff --git a/kmicromail/libetpan/generic/libetpan_version.h b/kmicromail/libetpan/generic/libetpan_version.h
new file mode 100644
index 0000000..5f9e5cf
--- a/dev/null
+++ b/kmicromail/libetpan/generic/libetpan_version.h
@@ -0,0 +1,51 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef LIBETPAN_VERSION_H
37
38#define LIBETPAN_VERSION_H
39
40#ifndef LIBETPAN_VERSION_MAJOR
41#define LIBETPAN_VERSION_MAJOR 0
42#endif
43
44#ifndef LIBETPAN_VERSION_MINOR
45#define LIBETPAN_VERSION_MINOR 32
46#endif
47
48int libetpan_get_version_major(void);
49int libetpan_get_version_minor(void);
50
51#endif
diff --git a/kmicromail/libetpan/generic/libetpan_version.h.in b/kmicromail/libetpan/generic/libetpan_version.h.in
new file mode 100644
index 0000000..ce1deb2
--- a/dev/null
+++ b/kmicromail/libetpan/generic/libetpan_version.h.in
@@ -0,0 +1,51 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef LIBETPAN_VERSION_H
37
38#define LIBETPAN_VERSION_H
39
40#ifndef LIBETPAN_VERSION_MAJOR
41#define LIBETPAN_VERSION_MAJOR @VERSION_MAJOR@
42#endif
43
44#ifndef LIBETPAN_VERSION_MINOR
45#define LIBETPAN_VERSION_MINOR @VERSION_MINOR@
46#endif
47
48int libetpan_get_version_major(void);
49int libetpan_get_version_minor(void);
50
51#endif
diff --git a/kmicromail/libetpan/generic/maildirdriver.c b/kmicromail/libetpan/generic/maildirdriver.c
new file mode 100644
index 0000000..7830ceb
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver.c
@@ -0,0 +1,625 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36
37/*
38 flags directory MUST be kept so that we can have other flags
39 than standards
40*/
41
42#include "maildirdriver.h"
43
44#include <stdio.h>
45#include <sys/types.h>
46#include <dirent.h>
47#include <unistd.h>
48#include <sys/stat.h>
49#include <ctype.h>
50#include <fcntl.h>
51#include <sys/mman.h>
52#include <stdlib.h>
53#include <string.h>
54
55#include "maildir.h"
56#include "maildriver_tools.h"
57#include "maildirdriver_message.h"
58#include "maildirdriver_tools.h"
59#include "mailmessage.h"
60#include "generic_cache.h"
61
62static int initialize(mailsession * session);
63
64static void uninitialize(mailsession * session);
65
66static int connect_path(mailsession * session, char * path);
67
68static int logout(mailsession * session);
69
70static int expunge_folder(mailsession * session);
71
72static int status_folder(mailsession * session, char * mb,
73 uint32_t * result_messages, uint32_t * result_recent,
74 uint32_t * result_unseen);
75
76static int recent_number(mailsession * session, char * mb,
77 uint32_t * result);
78
79static int unseen_number(mailsession * session, char * mb,
80 uint32_t * result);
81
82static int messages_number(mailsession * session, char * mb,
83 uint32_t * result);
84
85static int append_message(mailsession * session,
86 char * message, size_t size);
87
88static int get_messages_list(mailsession * session,
89 struct mailmessage_list ** result);
90
91static int get_envelopes_list(mailsession * session,
92 struct mailmessage_list * env_list);
93
94static int check_folder(mailsession * session);
95
96static int get_message_by_uid(mailsession * session,
97 const char * uid, mailmessage ** result);
98
99static mailsession_driver local_maildir_session_driver = {
100 .sess_name = "maildir",
101
102 .sess_initialize = initialize,
103 .sess_uninitialize = uninitialize,
104
105 .sess_parameters = NULL,
106
107 .sess_connect_stream = NULL,
108 .sess_connect_path = connect_path,
109 .sess_starttls = NULL,
110 .sess_login = NULL,
111 .sess_logout = logout,
112 .sess_noop = NULL,
113
114 .sess_build_folder_name = NULL,
115 .sess_create_folder = NULL,
116 .sess_delete_folder = NULL,
117 .sess_rename_folder = NULL,
118 .sess_check_folder = check_folder,
119 .sess_examine_folder = NULL,
120 .sess_select_folder = NULL,
121 .sess_expunge_folder = expunge_folder,
122 .sess_status_folder = status_folder,
123 .sess_messages_number = messages_number,
124 .sess_recent_number = recent_number,
125 .sess_unseen_number = unseen_number,
126 .sess_list_folders = NULL,
127 .sess_lsub_folders = NULL,
128 .sess_subscribe_folder = NULL,
129 .sess_unsubscribe_folder = NULL,
130
131 .sess_append_message = append_message,
132 .sess_copy_message = NULL,
133 .sess_move_message = NULL,
134
135 .sess_get_messages_list = get_messages_list,
136 .sess_get_envelopes_list = get_envelopes_list,
137 .sess_remove_message = NULL,
138#if 0
139 .sess_search_messages = maildriver_generic_search_messages,
140#endif
141
142 .sess_get_message = NULL,
143 .sess_get_message_by_uid = get_message_by_uid,
144};
145
146mailsession_driver * maildir_session_driver = &local_maildir_session_driver;
147
148
149static int flags_store_process(struct maildir * md,
150 struct mail_flags_store * flags_store);
151
152
153static inline struct maildir_session_state_data * get_data(mailsession * session)
154{
155 return session->sess_data;
156}
157
158static struct maildir * get_maildir_session(mailsession * session)
159{
160 return get_data(session)->md_session;
161}
162
163static int initialize(mailsession * session)
164{
165 struct maildir_session_state_data * data;
166
167 data = malloc(sizeof(* data));
168 if (data == NULL)
169 goto err;
170
171 data->md_session = NULL;
172
173 data->md_flags_store = mail_flags_store_new();
174 if (data->md_flags_store == NULL)
175 goto free;
176
177 session->sess_data = data;
178
179 return MAIL_NO_ERROR;
180
181 free:
182 free(data);
183 err:
184 return MAIL_ERROR_MEMORY;
185}
186
187static void uninitialize(mailsession * session)
188{
189 struct maildir_session_state_data * data;
190
191 data = get_data(session);
192
193 if (data->md_session != NULL)
194 flags_store_process(data->md_session, data->md_flags_store);
195
196 mail_flags_store_free(data->md_flags_store);
197 if (data->md_session != NULL)
198 maildir_free(data->md_session);
199
200 free(data);
201
202 session->sess_data = NULL;
203}
204
205
206static int connect_path(mailsession * session, char * path)
207{
208 struct maildir * md;
209 int res;
210 int r;
211
212 if (get_maildir_session(session) != NULL) {
213 res = MAIL_ERROR_BAD_STATE;
214 goto err;
215 }
216
217 md = maildir_new(path);
218 if (md == NULL) {
219 res = MAIL_ERROR_MEMORY;
220 goto err;
221 }
222
223 r = maildir_update(md);
224 if (r != MAILDIR_NO_ERROR) {
225 res = maildirdriver_maildir_error_to_mail_error(r);
226 goto free;
227 }
228
229 get_data(session)->md_session = md;
230
231 return MAIL_NO_ERROR;
232
233 free:
234 maildir_free(md);
235 err:
236 return res;
237}
238
239static int logout(mailsession * session)
240{
241 struct maildir * md;
242
243 check_folder(session);
244
245 md = get_maildir_session(session);
246 if (md == NULL)
247 return MAIL_ERROR_BAD_STATE;
248
249 maildir_free(md);
250 get_data(session)->md_session = NULL;
251
252 return MAIL_NO_ERROR;
253}
254
255/* folders operations */
256
257static int status_folder(mailsession * session, char * mb,
258 uint32_t * result_messages, uint32_t * result_recent,
259 uint32_t * result_unseen)
260{
261 int r;
262 struct maildir * md;
263 unsigned int i;
264 uint32_t messages;
265 uint32_t recent;
266 uint32_t unseen;
267
268 check_folder(session);
269
270 md = get_maildir_session(session);
271 if (md == NULL)
272 return MAIL_ERROR_BAD_STATE;
273
274 r = maildir_update(md);
275 if (r != MAILDIR_NO_ERROR)
276 return maildirdriver_maildir_error_to_mail_error(r);
277
278 messages = 0;
279 recent = 0;
280 unseen = 0;
281 for(i = 0 ; i < carray_count(md->mdir_msg_list) ; i ++) {
282 struct maildir_msg * msg;
283
284 msg = carray_get(md->mdir_msg_list, i);
285 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
286 recent ++;
287 if ((msg->msg_flags & MAILDIR_FLAG_SEEN) == 0)
288 unseen ++;
289 messages ++;
290 }
291
292 * result_messages = messages;
293 * result_recent = recent;
294 * result_unseen = unseen;
295
296 return MAIL_NO_ERROR;
297}
298
299static int messages_number(mailsession * session, char * mb,
300 uint32_t * result)
301{
302 struct maildir * md;
303 int r;
304
305 md = get_maildir_session(session);
306 if (md == NULL)
307 return MAIL_ERROR_BAD_STATE;
308
309 r = maildir_update(md);
310 if (r != MAILDIR_NO_ERROR)
311 return maildirdriver_maildir_error_to_mail_error(r);
312
313 * result = carray_count(md->mdir_msg_list);
314
315 return MAIL_NO_ERROR;
316}
317
318static int unseen_number(mailsession * session, char * mb,
319 uint32_t * result)
320{
321 uint32_t messages;
322 uint32_t recent;
323 uint32_t unseen;
324 int r;
325
326 r = status_folder(session, mb, &messages, &recent, &unseen);
327 if (r != MAIL_NO_ERROR)
328 return r;
329
330 * result = unseen;
331
332 return MAIL_NO_ERROR;
333}
334
335static int recent_number(mailsession * session, char * mb,
336 uint32_t * result)
337{
338 uint32_t messages;
339 uint32_t recent;
340 uint32_t unseen;
341 int r;
342
343 r = status_folder(session, mb, &messages, &recent, &unseen);
344 if (r != MAIL_NO_ERROR)
345 return r;
346
347 * result = recent;
348
349 return MAIL_NO_ERROR;
350}
351
352
353/* messages operations */
354
355static int append_message(mailsession * session,
356 char * message, size_t size)
357{
358 struct maildir * md;
359 int r;
360
361 md = get_maildir_session(session);
362 if (md == NULL)
363 return MAIL_ERROR_BAD_STATE;
364
365 r = maildir_message_add(md, message, size);
366 if (r != MAILDIR_NO_ERROR)
367 return maildirdriver_maildir_error_to_mail_error(r);
368
369 return MAIL_NO_ERROR;
370}
371
372static int get_messages_list(mailsession * session,
373 struct mailmessage_list ** result)
374{
375 struct maildir * md;
376 int r;
377 struct mailmessage_list * env_list;
378 int res;
379
380 md = get_maildir_session(session);
381 if (md == NULL)
382 return MAIL_ERROR_BAD_STATE;
383
384 r = maildir_update(md);
385 if (r != MAILDIR_NO_ERROR) {
386 res = maildirdriver_maildir_error_to_mail_error(r);
387 goto err;
388 }
389
390 r = maildir_get_messages_list(session, md,
391 maildir_message_driver, &env_list);
392 if (r != MAILDIR_NO_ERROR) {
393 res = r;
394 goto free_list;
395 }
396
397 * result = env_list;
398
399 return MAIL_NO_ERROR;
400
401 free_list:
402 mailmessage_list_free(env_list);
403 err:
404 return res;
405}
406
407static int get_envelopes_list(mailsession * session,
408 struct mailmessage_list * env_list)
409{
410 int r;
411 struct maildir * md;
412 unsigned int i;
413 int res;
414
415 check_folder(session);
416
417 md = get_maildir_session(session);
418 if (md == NULL) {
419 res = MAIL_ERROR_BAD_STATE;
420 goto err;
421 }
422
423 r = maildir_update(md);
424 if (r != MAILDIR_NO_ERROR) {
425 res = maildirdriver_maildir_error_to_mail_error(r);
426 goto err;
427 }
428
429 r = maildriver_generic_get_envelopes_list(session, env_list);
430 if (r != MAIL_NO_ERROR) {
431 res = r;
432 goto err;
433 }
434
435 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i++) {
436 struct maildir_msg * md_msg;
437 mailmessage * msg;
438 uint32_t driver_flags;
439 clist * ext;
440 chashdatum key;
441 chashdatum value;
442
443 msg = carray_get(env_list->msg_tab, i);
444
445 key.data = msg->msg_uid;
446 key.len = strlen(msg->msg_uid);
447 r = chash_get(md->mdir_msg_hash, &key, &value);
448 if (r < 0)
449 continue;
450
451 md_msg = value.data;
452
453 driver_flags = maildirdriver_maildir_flags_to_flags(md_msg->msg_flags);
454
455 if (msg->msg_flags == NULL) {
456 ext = clist_new();
457 if (ext == NULL) {
458 res = MAIL_ERROR_MEMORY;
459 continue;
460 }
461
462 msg->msg_flags = mail_flags_new(driver_flags, ext);
463 if (msg->msg_flags == NULL) {
464 clist_free(ext);
465 res = MAIL_ERROR_MEMORY;
466 continue;
467 }
468
469 if ((md_msg->msg_flags & MAILDIR_FLAG_NEW) != 0) {
470 mail_flags_store_set(get_data(session)->md_flags_store, msg);
471 }
472 }
473 else {
474 msg->msg_flags->fl_flags &= MAIL_FLAG_FORWARDED;
475 msg->msg_flags->fl_flags |= driver_flags;
476 }
477 }
478
479 return MAIL_NO_ERROR;
480
481 err:
482 return res;
483}
484
485
486static int expunge_folder(mailsession * session)
487{
488 unsigned int i;
489 int r;
490 int res;
491 struct maildir * md;
492
493 check_folder(session);
494
495 md = get_maildir_session(session);
496 if (md == NULL)
497 return MAIL_ERROR_BAD_STATE;
498
499 r = maildir_update(md);
500 if (r != MAILDIR_NO_ERROR) {
501 res = maildirdriver_maildir_error_to_mail_error(r);
502 goto err;
503 }
504
505 for(i = 0 ; i < carray_count(md->mdir_msg_list) ; i++) {
506 struct maildir_msg * md_msg;
507
508 md_msg = carray_get(md->mdir_msg_list, i);
509
510 if ((md_msg->msg_flags & MAILDIR_FLAG_TRASHED) != 0)
511 maildir_message_remove(md, md_msg->msg_uid);
512 }
513
514 return MAIL_NO_ERROR;
515
516 err:
517 return res;
518}
519
520
521static int flags_store_process(struct maildir * md,
522 struct mail_flags_store * flags_store)
523{
524 unsigned int i;
525
526 if (carray_count(flags_store->fls_tab) == 0)
527 return MAIL_NO_ERROR;
528
529 for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
530 mailmessage * msg;
531 uint32_t md_flags;
532
533 msg = carray_get(flags_store->fls_tab, i);
534 md_flags = maildirdriver_flags_to_maildir_flags(msg->msg_flags->fl_flags);
535 md_flags &= ~MAILDIR_FLAG_NEW;
536
537 maildir_message_change_flags(md, msg->msg_uid, md_flags);
538 }
539
540 mail_flags_store_clear(flags_store);
541
542 return MAIL_NO_ERROR;
543}
544
545
546
547static int check_folder(mailsession * session)
548{
549 struct mail_flags_store * flags_store;
550 struct maildir_session_state_data * data;
551 struct maildir * md;
552
553 md = get_maildir_session(session);
554 if (md == NULL)
555 return MAIL_ERROR_BAD_STATE;
556
557 data = get_data(session);
558 flags_store = data->md_flags_store;
559
560 return flags_store_process(md, flags_store);
561}
562
563static int get_message_by_uid(mailsession * session,
564 const char * uid, mailmessage ** result)
565{
566 int r;
567 struct maildir * md;
568 int res;
569 mailmessage * msg;
570 char * msg_filename;
571 struct stat stat_info;
572
573 md = get_maildir_session(session);
574
575 /* update maildir data */
576
577 r = maildir_update(md);
578 if (r != MAILDIR_NO_ERROR) {
579 res = maildirdriver_maildir_error_to_mail_error(r);
580 goto err;
581 }
582
583 msg_filename = maildir_message_get(md, uid);
584 if (msg_filename == NULL) {
585 res = MAIL_ERROR_INVAL;
586 goto err;
587 }
588
589 r = stat(msg_filename, &stat_info);
590 free(msg_filename);
591 if (r < 0) {
592 res = MAIL_ERROR_INVAL;
593 goto err;
594 }
595
596 /* create message */
597
598 msg = mailmessage_new();
599 if (msg == NULL) {
600 res = MAIL_ERROR_MEMORY;
601 goto err;
602 }
603
604 r = mailmessage_init(msg, session, maildir_message_driver,
605 0, stat_info.st_size);
606 if (r != MAIL_NO_ERROR) {
607 mailmessage_free(msg);
608 res = r;
609 goto err;
610 }
611
612 msg->msg_uid = strdup(uid);
613 if (msg->msg_uid == NULL) {
614 mailmessage_free(msg);
615 res = r;
616 goto err;
617 }
618
619 * result = msg;
620
621 return MAIL_NO_ERROR;
622
623 err:
624 return res;
625}
diff --git a/kmicromail/libetpan/generic/maildirdriver.h b/kmicromail/libetpan/generic/maildirdriver.h
new file mode 100644
index 0000000..f59cf3e
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver.h
@@ -0,0 +1,53 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIRDRIVER_H
37
38#define MAILDIRDRIVER_H
39
40#include <libetpan/maildriver.h>
41#include <libetpan/maildirdriver_types.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47extern mailsession_driver * maildir_session_driver;
48
49#ifdef __cplusplus
50}
51#endif
52
53#endif
diff --git a/kmicromail/libetpan/generic/maildirdriver_cached.c b/kmicromail/libetpan/generic/maildirdriver_cached.c
new file mode 100644
index 0000000..503d1c9
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_cached.c
@@ -0,0 +1,1080 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "maildirdriver.h"
37
38#include <stdio.h>
39#include <sys/types.h>
40#include <dirent.h>
41#include <unistd.h>
42#include <sys/stat.h>
43#include <ctype.h>
44#include <fcntl.h>
45#include <sys/mman.h>
46#include <stdlib.h>
47#include <string.h>
48
49#include "mail.h"
50#include "maildir.h"
51#include "maildriver_tools.h"
52#include "maildirdriver_tools.h"
53#include "maildirdriver_cached_message.h"
54#include "mailmessage.h"
55#include "generic_cache.h"
56#include "imfcache.h"
57#include "mail_cache_db.h"
58#include "libetpan-config.h"
59
60static int initialize(mailsession * session);
61
62static void uninitialize(mailsession * session);
63
64static int parameters(mailsession * session,
65 int id, void * value);
66
67static int connect_path(mailsession * session, char * path);
68
69static int logout(mailsession * session);
70
71static int expunge_folder(mailsession * session);
72
73static int status_folder(mailsession * session, char * mb,
74 uint32_t * result_messages, uint32_t * result_recent,
75 uint32_t * result_unseen);
76
77static int recent_number(mailsession * session, char * mb,
78 uint32_t * result);
79
80static int unseen_number(mailsession * session, char * mb,
81 uint32_t * result);
82
83static int messages_number(mailsession * session, char * mb,
84 uint32_t * result);
85
86static int append_message(mailsession * session,
87 char * message, size_t size);
88
89static int get_messages_list(mailsession * session,
90 struct mailmessage_list ** result);
91
92static int get_envelopes_list(mailsession * session,
93 struct mailmessage_list * env_list);
94
95static int check_folder(mailsession * session);
96
97static int get_message(mailsession * session,
98 uint32_t num, mailmessage ** result);
99
100static int get_message_by_uid(mailsession * session,
101 const char * uid, mailmessage ** result);
102
103static mailsession_driver local_maildir_cached_session_driver = {
104 .sess_name = "maildir-cached",
105
106 .sess_initialize = initialize,
107 .sess_uninitialize = uninitialize,
108
109 .sess_parameters = parameters,
110
111 .sess_connect_stream = NULL,
112 .sess_connect_path = connect_path,
113 .sess_starttls = NULL,
114 .sess_login = NULL,
115 .sess_logout = logout,
116 .sess_noop = NULL,
117
118 .sess_build_folder_name = NULL,
119 .sess_create_folder = NULL,
120 .sess_delete_folder = NULL,
121 .sess_rename_folder = NULL,
122 .sess_check_folder = check_folder,
123 .sess_examine_folder = NULL,
124 .sess_select_folder = NULL,
125 .sess_expunge_folder = expunge_folder,
126 .sess_status_folder = status_folder,
127 .sess_messages_number = messages_number,
128 .sess_recent_number = recent_number,
129 .sess_unseen_number = unseen_number,
130 .sess_list_folders = NULL,
131 .sess_lsub_folders = NULL,
132 .sess_subscribe_folder = NULL,
133 .sess_unsubscribe_folder = NULL,
134
135 .sess_append_message = append_message,
136 .sess_copy_message = NULL,
137 .sess_move_message = NULL,
138
139 .sess_get_messages_list = get_messages_list,
140 .sess_get_envelopes_list = get_envelopes_list,
141 .sess_remove_message = NULL,
142#if 0
143 .sess_search_messages = maildriver_generic_search_messages,
144#endif
145
146 .sess_get_message = get_message,
147 .sess_get_message_by_uid = get_message_by_uid,
148};
149
150mailsession_driver * maildir_cached_session_driver =
151&local_maildir_cached_session_driver;
152
153
154static inline struct maildir_cached_session_state_data *
155get_cached_data(mailsession * session)
156{
157 return session->sess_data;
158}
159
160static inline mailsession * get_ancestor(mailsession * session)
161{
162 return get_cached_data(session)->md_ancestor;
163}
164
165static inline struct maildir_session_state_data *
166get_ancestor_data(mailsession * session)
167{
168 return get_ancestor(session)->sess_data;
169}
170
171
172static struct maildir * get_maildir_session(mailsession * session)
173{
174 return get_ancestor_data(session)->md_session;
175}
176
177static int initialize(mailsession * session)
178{
179 struct maildir_cached_session_state_data * data;
180
181 data = malloc(sizeof(* data));
182 if (data == NULL)
183 goto err;
184
185 data->md_ancestor = mailsession_new(maildir_session_driver);
186 if (data->md_ancestor == NULL)
187 goto free;
188
189 data->md_flags_store = mail_flags_store_new();
190 if (data->md_flags_store == NULL)
191 goto free_session;
192
193 data->md_quoted_mb = NULL;
194 data->md_cache_directory[0] = '\0';
195 data->md_flags_directory[0] = '\0';
196
197 session->sess_data = data;
198
199 return MAIL_NO_ERROR;
200
201 free_session:
202 mailsession_free(data->md_ancestor);
203 free:
204 free(data);
205 err:
206 return MAIL_ERROR_MEMORY;
207}
208
209static void
210free_quoted_mb(struct maildir_cached_session_state_data * maildir_cached_data)
211{
212 if (maildir_cached_data->md_quoted_mb != NULL) {
213 free(maildir_cached_data->md_quoted_mb);
214 maildir_cached_data->md_quoted_mb = NULL;
215 }
216}
217
218static int
219write_cached_flags(struct mail_cache_db * cache_db,
220 MMAPString * mmapstr,
221 char * uid, struct mail_flags * flags);
222
223#define ENV_NAME "env.db"
224#define FLAGS_NAME "flags.db"
225
226static int flags_store_process(char * flags_directory, char * quoted_mb,
227 struct mail_flags_store * flags_store)
228{
229 char filename_flags[PATH_MAX];
230 struct mail_cache_db * cache_db_flags;
231 MMAPString * mmapstr;
232 unsigned int i;
233 int r;
234 int res;
235
236 if (carray_count(flags_store->fls_tab) == 0)
237 return MAIL_NO_ERROR;
238
239 if (quoted_mb == NULL)
240 return MAIL_NO_ERROR;
241
242 snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s",
243 flags_directory, MAIL_DIR_SEPARATOR, quoted_mb,
244 MAIL_DIR_SEPARATOR, FLAGS_NAME);
245
246 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
247 if (r < 0) {
248 res = MAIL_ERROR_FILE;
249 goto err;
250 }
251
252 mmapstr = mmap_string_new("");
253 if (mmapstr == NULL) {
254 res = MAIL_ERROR_MEMORY;
255 goto close_db_flags;
256 }
257
258 for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
259 mailmessage * msg;
260
261 msg = carray_get(flags_store->fls_tab, i);
262
263 r = write_cached_flags(cache_db_flags, mmapstr,
264 msg->msg_uid, msg->msg_flags);
265 if (r != MAIL_NO_ERROR) {
266 /* ignore errors */
267 }
268 }
269
270 mmap_string_free(mmapstr);
271 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
272
273 mail_flags_store_clear(flags_store);
274
275 return MAIL_NO_ERROR;
276
277 close_db_flags:
278 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
279 err:
280 return res;
281}
282
283static void uninitialize(mailsession * session)
284{
285 struct maildir_cached_session_state_data * data;
286
287 data = get_cached_data(session);
288
289 flags_store_process(data->md_flags_directory,
290 data->md_quoted_mb,
291 data->md_flags_store);
292
293 mail_flags_store_free(data->md_flags_store);
294 mailsession_free(data->md_ancestor);
295 free_quoted_mb(data);
296 free(data);
297
298 session->sess_data = data;
299}
300
301
302static int parameters(mailsession * session,
303 int id, void * value)
304{
305 struct maildir_cached_session_state_data * data;
306 int r;
307
308 data = get_cached_data(session);
309
310 switch (id) {
311 case MAILDIRDRIVER_CACHED_SET_CACHE_DIRECTORY:
312 strncpy(data->md_cache_directory, value, PATH_MAX);
313 data->md_cache_directory[PATH_MAX - 1] = '\0';
314
315 r = generic_cache_create_dir(data->md_cache_directory);
316 if (r != MAIL_NO_ERROR)
317 return r;
318
319 return MAIL_NO_ERROR;
320
321 case MAILDIRDRIVER_CACHED_SET_FLAGS_DIRECTORY:
322 strncpy(data->md_flags_directory, value, PATH_MAX);
323 data->md_flags_directory[PATH_MAX - 1] = '\0';
324
325 r = generic_cache_create_dir(data->md_flags_directory);
326 if (r != MAIL_NO_ERROR)
327 return r;
328
329 return MAIL_NO_ERROR;
330
331 default:
332 return mailsession_parameters(data->md_ancestor, id, value);
333 }
334}
335
336
337static int get_cache_folder(mailsession * session, char ** result)
338{
339 struct maildir * md;
340 char * quoted_mb;
341 int res;
342 int r;
343 char key[PATH_MAX];
344 struct maildir_cached_session_state_data * data;
345
346 md = get_maildir_session(session);
347 data = get_cached_data(session);
348
349 quoted_mb = maildriver_quote_mailbox(md->mdir_path);
350 if (quoted_mb == NULL) {
351 res = MAIL_ERROR_MEMORY;
352 goto err;
353 }
354
355 snprintf(key, PATH_MAX, "%s/%s", data->md_cache_directory, quoted_mb);
356 r = generic_cache_create_dir(key);
357 if (r != MAIL_NO_ERROR) {
358 res = r;
359 goto free_quoted_mb;
360 }
361
362 snprintf(key, PATH_MAX, "%s/%s", data->md_flags_directory, quoted_mb);
363 r = generic_cache_create_dir(key);
364 if (r != MAIL_NO_ERROR) {
365 res = r;
366 goto free_quoted_mb;
367 }
368
369 * result = quoted_mb;
370
371 return MAIL_NO_ERROR;
372
373 free_quoted_mb:
374 free(quoted_mb);
375 err:
376 return res;
377}
378
379
380static int connect_path(mailsession * session, char * path)
381{
382 int r;
383 int res;
384 char * quoted_mb;
385
386 r = mailsession_connect_path(get_ancestor(session), path);
387 if (r != MAIL_NO_ERROR) {
388 res = r;
389 goto err;
390 }
391
392 r = get_cache_folder(session, &quoted_mb);
393 if (r != MAIL_NO_ERROR) {
394 res = r;
395 goto logout;
396 }
397
398 get_cached_data(session)->md_quoted_mb = quoted_mb;
399
400 return MAILDIR_NO_ERROR;
401
402 logout:
403 mailsession_logout(get_ancestor(session));
404 err:
405 return res;
406}
407
408static int logout(mailsession * session)
409{
410 struct maildir_cached_session_state_data * data;
411 int r;
412
413 data = get_cached_data(session);
414
415 flags_store_process(data->md_flags_directory,
416 data->md_quoted_mb, data->md_flags_store);
417
418 r = mailsession_logout(get_ancestor(session));
419 if (r != MAIL_NO_ERROR)
420 return r;
421
422 free_quoted_mb(get_cached_data(session));
423
424 return MAIL_NO_ERROR;
425}
426
427static int status_folder(mailsession * session, char * mb,
428 uint32_t * result_messages, uint32_t * result_recent,
429 uint32_t * result_unseen)
430{
431 return mailsession_status_folder(get_ancestor(session), mb,
432 result_messages, result_recent, result_unseen);
433}
434
435static int messages_number(mailsession * session, char * mb,
436 uint32_t * result)
437{
438 return mailsession_messages_number(get_ancestor(session), mb, result);
439}
440
441static int unseen_number(mailsession * session, char * mb,
442 uint32_t * result)
443{
444 return mailsession_unseen_number(get_ancestor(session), mb, result);
445}
446
447static int recent_number(mailsession * session, char * mb,
448 uint32_t * result)
449{
450 return mailsession_recent_number(get_ancestor(session), mb, result);
451}
452
453
454static int append_message(mailsession * session,
455 char * message, size_t size)
456{
457 return mailsession_append_message(get_ancestor(session), message, size);
458}
459
460
461#define UID_NAME "uid.db"
462
463static int uid_clean_up(struct mail_cache_db * uid_db,
464 struct mailmessage_list * env_list)
465{
466 chash * hash_exist;
467 int res;
468 int r;
469 unsigned int i;
470 chashdatum key;
471 chashdatum value;
472 char key_str[PATH_MAX];
473
474 /* flush cache */
475
476 hash_exist = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYALL);
477 if (hash_exist == NULL) {
478 res = MAIL_ERROR_MEMORY;
479 goto err;
480 }
481
482 value.data = NULL;
483 value.len = 0;
484
485 key.data = "max-uid";
486 key.len = strlen("max-uid");
487 r = chash_set(hash_exist, &key, &value, NULL);
488
489 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
490 mailmessage * msg;
491
492 msg = carray_get(env_list->msg_tab, i);
493
494 value.data = NULL;
495 value.len = 0;
496
497 key.data = msg->msg_uid;
498 key.len = strlen(msg->msg_uid);
499 r = chash_set(hash_exist, &key, &value, NULL);
500 if (r < 0) {
501 res = MAIL_ERROR_MEMORY;
502 goto free;
503 }
504
505 snprintf(key_str, sizeof(key_str), "uid-%lu",
506 (unsigned long) msg->msg_index);
507 key.data = key_str;
508 key.len = strlen(key_str);
509 r = chash_set(hash_exist, &key, &value, NULL);
510 if (r < 0) {
511 res = MAIL_ERROR_MEMORY;
512 goto free;
513 }
514 }
515
516 mail_cache_db_clean_up(uid_db, hash_exist);
517
518 chash_free(hash_exist);
519
520 return MAIL_NO_ERROR;
521
522 free:
523 chash_free(hash_exist);
524 err:
525 return res;
526}
527
528static int get_messages_list(mailsession * session,
529 struct mailmessage_list ** result)
530{
531 struct maildir * md;
532 int r;
533 struct mailmessage_list * env_list;
534 int res;
535 uint32_t max_uid;
536 char filename[PATH_MAX];
537 struct mail_cache_db * uid_db;
538 void * value;
539 size_t value_len;
540 unsigned long i;
541 struct maildir_cached_session_state_data * data;
542 char key[PATH_MAX];
543
544 data = get_cached_data(session);
545
546 md = get_maildir_session(session);
547 if (md == NULL) {
548 res = MAIL_ERROR_BAD_STATE;
549 goto err;
550 }
551
552 check_folder(session);
553
554 r = maildir_update(md);
555 if (r != MAILDIR_NO_ERROR) {
556 res = maildirdriver_maildir_error_to_mail_error(r);
557 goto err;
558 }
559
560 r = maildir_get_messages_list(session, md,
561 maildir_cached_message_driver, &env_list);
562 if (r != MAILDIR_NO_ERROR) {
563 res = r;
564 goto err;
565 }
566
567 /* read/write DB */
568
569 snprintf(filename, sizeof(filename), "%s%c%s%c%s",
570 data->md_flags_directory, MAIL_DIR_SEPARATOR, data->md_quoted_mb,
571 MAIL_DIR_SEPARATOR, UID_NAME);
572
573 r = mail_cache_db_open_lock(filename, &uid_db);
574 if (r < 0) {
575 res = MAIL_ERROR_MEMORY;
576 goto free_list;
577 }
578
579 max_uid = 0;
580 r = mail_cache_db_get(uid_db, "max-uid", sizeof("max-uid") - 1,
581 &value, &value_len);
582 if (r == 0) {
583 memcpy(&max_uid, value, sizeof(max_uid));
584 }
585
586 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
587 mailmessage * msg;
588 uint32_t index;
589
590 msg = carray_get(env_list->msg_tab, i);
591
592 r = mail_cache_db_get(uid_db, msg->msg_uid,
593 strlen(msg->msg_uid), &value, &value_len);
594 if (r < 0) {
595 max_uid ++;
596 msg->msg_index = max_uid;
597 mail_cache_db_put(uid_db, msg->msg_uid,
598 strlen(msg->msg_uid), &msg->msg_index, sizeof(msg->msg_index));
599
600 snprintf(key, sizeof(key), "uid-%lu", (unsigned long) msg->msg_index);
601 mail_cache_db_put(uid_db, key, strlen(key),
602 msg->msg_uid, strlen(msg->msg_uid));
603 }
604 else {
605 memcpy(&index, value, sizeof(index));
606 msg->msg_index = index;
607 }
608 }
609
610 mail_cache_db_put(uid_db, "max-uid", sizeof("max-uid") - 1,
611 &max_uid, sizeof(max_uid));
612
613 uid_clean_up(uid_db, env_list);
614
615 mail_cache_db_close_unlock(filename, uid_db);
616
617 * result = env_list;
618
619 return MAIL_NO_ERROR;
620
621 free_list:
622 mailmessage_list_free(env_list);
623 err:
624 return res;
625}
626
627static int
628get_cached_flags(struct mail_cache_db * cache_db,
629 MMAPString * mmapstr,
630 mailsession * session,
631 char * uid,
632 struct mail_flags ** result)
633{
634 int r;
635 char keyname[PATH_MAX];
636 struct mail_flags * flags;
637 int res;
638
639 snprintf(keyname, PATH_MAX, "%s-flags", uid);
640
641 r = generic_cache_flags_read(cache_db, mmapstr, keyname, &flags);
642 if (r != MAIL_NO_ERROR) {
643 res = r;
644 goto err;
645 }
646
647 * result = flags;
648
649 return MAIL_NO_ERROR;
650
651 err:
652 return res;
653}
654
655static int
656get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
657 mailsession * session, char * uid,
658 struct mailimf_fields ** result)
659{
660 int r;
661 char keyname[PATH_MAX];
662 struct mailimf_fields * fields;
663 int res;
664
665 snprintf(keyname, PATH_MAX, "%s-envelope", uid);
666
667 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields);
668 if (r != MAIL_NO_ERROR) {
669 res = r;
670 goto err;
671 }
672
673 * result = fields;
674
675 return MAIL_NO_ERROR;
676
677 err:
678 return res;
679}
680
681static int
682write_cached_envelope(struct mail_cache_db * cache_db,
683 MMAPString * mmapstr,
684 mailsession * session, char * uid,
685 struct mailimf_fields * fields)
686{
687 int r;
688 char keyname[PATH_MAX];
689 int res;
690
691 snprintf(keyname, PATH_MAX, "%s-envelope", uid);
692
693 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields);
694 if (r != MAIL_NO_ERROR) {
695 res = r;
696 goto err;
697 }
698
699 return MAIL_NO_ERROR;
700
701 err:
702 return res;
703}
704
705static int
706write_cached_flags(struct mail_cache_db * cache_db,
707 MMAPString * mmapstr,
708 char * uid, struct mail_flags * flags)
709{
710 int r;
711 char keyname[PATH_MAX];
712 int res;
713
714 snprintf(keyname, PATH_MAX, "%s-flags", uid);
715
716 r = generic_cache_flags_write(cache_db, mmapstr, keyname, flags);
717 if (r != MAIL_NO_ERROR) {
718 res = r;
719 goto err;
720 }
721
722 return MAIL_NO_ERROR;
723
724 err:
725 return res;
726}
727
728
729static int get_envelopes_list(mailsession * session,
730 struct mailmessage_list * env_list)
731{
732 int r;
733 unsigned int i;
734 int res;
735 struct maildir_cached_session_state_data * data;
736 char filename_env[PATH_MAX];
737 char filename_flags[PATH_MAX];
738 struct mail_cache_db * cache_db_env;
739 struct mail_cache_db * cache_db_flags;
740 MMAPString * mmapstr;
741
742 data = get_cached_data(session);
743
744 flags_store_process(data->md_flags_directory,
745 data->md_quoted_mb, data->md_flags_store);
746
747 mmapstr = mmap_string_new("");
748 if (mmapstr == NULL) {
749 res = MAIL_ERROR_MEMORY;
750 goto err;
751 }
752
753 snprintf(filename_env, PATH_MAX, "%s%c%s%c%s",
754 data->md_cache_directory, MAIL_DIR_SEPARATOR, data->md_quoted_mb,
755 MAIL_DIR_SEPARATOR, ENV_NAME);
756
757 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
758 if (r < 0) {
759 res = MAIL_ERROR_MEMORY;
760 goto free_mmapstr;
761 }
762
763 snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s",
764 data->md_flags_directory, MAIL_DIR_SEPARATOR, data->md_quoted_mb,
765 MAIL_DIR_SEPARATOR, FLAGS_NAME);
766
767 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
768 if (r < 0) {
769 res = MAIL_ERROR_FILE;
770 goto close_db_env;
771 }
772
773 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i++) {
774 mailmessage * msg;
775 struct mailimf_fields * fields;
776 struct mail_flags * flags;
777
778 msg = carray_get(env_list->msg_tab, i);
779
780 if (msg->msg_fields == NULL) {
781 r = get_cached_envelope(cache_db_env, mmapstr, session,
782 msg->msg_uid, &fields);
783 if (r == MAIL_NO_ERROR) {
784 msg->msg_cached = TRUE;
785 msg->msg_fields = fields;
786 }
787 }
788
789 if (msg->msg_flags == NULL) {
790 r = get_cached_flags(cache_db_flags, mmapstr,
791 session, msg->msg_uid, &flags);
792 if (r == MAIL_NO_ERROR) {
793 msg->msg_flags = flags;
794 }
795 }
796 }
797
798 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
799 mail_cache_db_close_unlock(filename_env, cache_db_env);
800
801 r = mailsession_get_envelopes_list(get_ancestor(session), env_list);
802 if (r != MAIL_NO_ERROR) {
803 res = r;
804 goto free_mmapstr;
805 }
806
807 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
808 if (r < 0) {
809 res = MAIL_ERROR_MEMORY;
810 goto free_mmapstr;
811 }
812
813 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
814 if (r < 0) {
815 res = MAIL_ERROR_FILE;
816 goto close_db_env;
817 }
818
819 /* must write cache */
820
821 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
822 mailmessage * msg;
823
824 msg = carray_get(env_list->msg_tab, i);
825
826 if (msg->msg_fields != NULL) {
827 if (!msg->msg_cached) {
828 /* msg->index is the numerical UID of the message */
829 r = write_cached_envelope(cache_db_env, mmapstr,
830 session, msg->msg_uid, msg->msg_fields);
831 }
832 }
833
834 if (msg->msg_flags != NULL) {
835 r = write_cached_flags(cache_db_flags, mmapstr,
836 msg->msg_uid, msg->msg_flags);
837 }
838 }
839
840 /* flush cache */
841
842 maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list);
843
844 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
845 mail_cache_db_close_unlock(filename_env, cache_db_env);
846
847 mmap_string_free(mmapstr);
848
849 return MAIL_NO_ERROR;
850
851 close_db_env:
852 mail_cache_db_close_unlock(filename_env, cache_db_env);
853 free_mmapstr:
854 mmap_string_free(mmapstr);
855 err:
856 return res;
857}
858
859static int expunge_folder(mailsession * session)
860{
861 return mailsession_expunge_folder(get_ancestor(session));
862}
863
864static int check_folder(mailsession * session)
865{
866 struct maildir_cached_session_state_data * data;
867
868 data = get_cached_data(session);
869
870 flags_store_process(data->md_flags_directory,
871 data->md_quoted_mb, data->md_flags_store);
872
873 return mailsession_check_folder(get_ancestor(session));
874}
875
876static int get_message(mailsession * session,
877 uint32_t num, mailmessage ** result)
878{
879 struct maildir * md;
880 int res;
881 mailmessage * msg;
882 char filename[PATH_MAX];
883 struct mail_cache_db * uid_db;
884 char * msg_filename;
885 struct stat stat_info;
886 char key_str[PATH_MAX];
887 void * value;
888 size_t value_len;
889 char uid[PATH_MAX];
890 struct maildir_cached_session_state_data * data;
891 int r;
892
893 data = get_cached_data(session);
894
895 md = get_maildir_session(session);
896
897 /* a get_messages_list() should have been done once before */
898
899 /* read DB */
900
901 snprintf(filename, sizeof(filename), "%s%c%s%c%s",
902 data->md_flags_directory, MAIL_DIR_SEPARATOR, data->md_quoted_mb,
903 MAIL_DIR_SEPARATOR, UID_NAME);
904
905 r = mail_cache_db_open_lock(filename, &uid_db);
906 if (r < 0) {
907 res = MAIL_ERROR_MEMORY;
908 goto err;
909 }
910
911 snprintf(key_str, sizeof(key_str), "uid-%lu", (unsigned long) num);
912
913 r = mail_cache_db_get(uid_db, key_str, strlen(key_str), &value, &value_len);
914 if (r < 0) {
915 res = MAIL_ERROR_INVAL;
916 goto close_db;
917 }
918
919 if (value_len >= PATH_MAX) {
920 res = MAIL_ERROR_INVAL;
921 goto close_db;
922 }
923
924 memcpy(uid, value, value_len);
925 uid[value_len] = '\0';
926
927 mail_cache_db_close_unlock(filename, uid_db);
928
929 /* update maildir data */
930
931 r = maildir_update(md);
932 if (r != MAILDIR_NO_ERROR) {
933 res = maildirdriver_maildir_error_to_mail_error(r);
934 goto err;
935 }
936
937 msg_filename = maildir_message_get(md, uid);
938 if (msg_filename == NULL) {
939 res = MAIL_ERROR_INVAL;
940 goto err;
941 }
942
943 r = stat(msg_filename, &stat_info);
944 free(msg_filename);
945 if (r < 0) {
946 res = MAIL_ERROR_INVAL;
947 goto err;
948 }
949
950 /* create message */
951
952 msg = mailmessage_new();
953 if (msg == NULL) {
954 res = MAIL_ERROR_MEMORY;
955 goto err;
956 }
957
958 r = mailmessage_init(msg, session, maildir_cached_message_driver,
959 num, stat_info.st_size);
960 if (r != MAIL_NO_ERROR) {
961 mailmessage_free(msg);
962 res = r;
963 goto err;
964 }
965
966 msg->msg_uid = strdup(uid);
967 if (msg->msg_uid == NULL) {
968 mailmessage_free(msg);
969 res = r;
970 goto err;
971 }
972
973 * result = msg;
974
975 return MAIL_NO_ERROR;
976
977 close_db:
978 mail_cache_db_close_unlock(filename, uid_db);
979 err:
980 return res;
981}
982
983
984static int get_message_by_uid(mailsession * session,
985 const char * uid, mailmessage ** result)
986{
987 int r;
988 struct maildir * md;
989 int res;
990 mailmessage * msg;
991 char filename[PATH_MAX];
992 struct mail_cache_db * uid_db;
993 char * msg_filename;
994 struct stat stat_info;
995 void * value;
996 size_t value_len;
997 struct maildir_cached_session_state_data * data;
998 uint32_t index;
999
1000 data = get_cached_data(session);
1001
1002 md = get_maildir_session(session);
1003
1004 /* a get_messages_list() should have been done once before */
1005
1006 /* read DB */
1007
1008 snprintf(filename, sizeof(filename), "%s%c%s%c%s",
1009 data->md_flags_directory, MAIL_DIR_SEPARATOR, data->md_quoted_mb,
1010 MAIL_DIR_SEPARATOR, UID_NAME);
1011
1012 r = mail_cache_db_open_lock(filename, &uid_db);
1013 if (r < 0) {
1014 res = MAIL_ERROR_MEMORY;
1015 goto err;
1016 }
1017
1018 r = mail_cache_db_get(uid_db, uid, strlen(uid), &value, &value_len);
1019 if (r < 0) {
1020 res = MAIL_ERROR_INVAL;
1021 goto close_db;
1022 }
1023
1024 memcpy(&index, value, sizeof(index));
1025
1026 mail_cache_db_close_unlock(filename, uid_db);
1027
1028 /* update maildir data */
1029
1030 r = maildir_update(md);
1031 if (r != MAILDIR_NO_ERROR) {
1032 res = maildirdriver_maildir_error_to_mail_error(r);
1033 goto err;
1034 }
1035
1036 msg_filename = maildir_message_get(md, uid);
1037 if (msg_filename == NULL) {
1038 res = MAIL_ERROR_INVAL;
1039 goto err;
1040 }
1041
1042 r = stat(msg_filename, &stat_info);
1043 free(msg_filename);
1044 if (r < 0) {
1045 res = MAIL_ERROR_INVAL;
1046 goto err;
1047 }
1048
1049 /* create message */
1050
1051 msg = mailmessage_new();
1052 if (msg == NULL) {
1053 res = MAIL_ERROR_MEMORY;
1054 goto err;
1055 }
1056
1057 r = mailmessage_init(msg, session, maildir_cached_message_driver,
1058 index, stat_info.st_size);
1059 if (r != MAIL_NO_ERROR) {
1060 mailmessage_free(msg);
1061 res = r;
1062 goto err;
1063 }
1064
1065 msg->msg_uid = strdup(uid);
1066 if (msg->msg_uid == NULL) {
1067 mailmessage_free(msg);
1068 res = r;
1069 goto err;
1070 }
1071
1072 * result = msg;
1073
1074 return MAIL_NO_ERROR;
1075
1076 close_db:
1077 mail_cache_db_close_unlock(filename, uid_db);
1078 err:
1079 return res;
1080}
diff --git a/kmicromail/libetpan/generic/maildirdriver_cached.h b/kmicromail/libetpan/generic/maildirdriver_cached.h
new file mode 100644
index 0000000..81de3c3
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_cached.h
@@ -0,0 +1,53 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIRDRIVER_CACHED_H
37
38#define MAILDIRDRIVER_CACHED_H
39
40#include <libetpan/maildriver.h>
41#include <libetpan/maildirdriver_types.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47extern mailsession_driver * maildir_cached_session_driver;
48
49#ifdef __cplusplus
50}
51#endif
52
53#endif
diff --git a/kmicromail/libetpan/generic/maildirdriver_cached_message.c b/kmicromail/libetpan/generic/maildirdriver_cached_message.c
new file mode 100644
index 0000000..51866aa
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_cached_message.c
@@ -0,0 +1,248 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "maildirdriver_message.h"
37
38#include "mailmessage_tools.h"
39#include "maildirdriver.h"
40#include "maildir.h"
41#include "generic_cache.h"
42
43#include <unistd.h>
44#include <sys/mman.h>
45#include <sys/types.h>
46#include <sys/stat.h>
47#include <fcntl.h>
48#include <string.h>
49#include <stdlib.h>
50
51static int prefetch(mailmessage * msg_info);
52
53static void prefetch_free(struct generic_message_t * msg);
54
55static int initialize(mailmessage * msg_info);
56
57static void check(mailmessage * msg_info);
58
59static mailmessage_driver local_maildir_cached_message_driver = {
60 .msg_name = "maildir-cached",
61
62 .msg_initialize = initialize,
63 .msg_uninitialize = mailmessage_generic_uninitialize,
64
65 .msg_flush = mailmessage_generic_flush,
66 .msg_check = check,
67
68 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
69
70 .msg_fetch = mailmessage_generic_fetch,
71 .msg_fetch_header = mailmessage_generic_fetch_header,
72 .msg_fetch_body = mailmessage_generic_fetch_header,
73 .msg_fetch_size = NULL,
74 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
75 .msg_fetch_section = mailmessage_generic_fetch_section,
76 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
77 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
78 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
79 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
80
81 .msg_get_flags = NULL,
82};
83
84mailmessage_driver * maildir_cached_message_driver =
85&local_maildir_cached_message_driver;
86
87struct maildir_msg_data {
88 int fd;
89};
90
91#if 0
92static inline struct maildir_cached_session_state_data *
93get_cached_session_data(mailmessage * msg)
94{
95 return msg->session->data;
96}
97
98static inline mailsession * cached_session_get_ancestor(mailsession * session)
99{
100 return get_data(session)->session;
101}
102
103static inline struct maildir_session_state_data *
104cached_session_get_ancestor_data(mailsession * session)
105{
106 return get_ancestor(session)->data;
107}
108
109static struct maildir * get_maildir_session(mailmessage * msg)
110{
111 return cached_session_get_ancestor_data(msg->session)->session;
112}
113#endif
114static inline struct maildir_cached_session_state_data *
115get_cached_session_data(mailmessage * msg)
116{
117 return msg->msg_session->sess_data;
118}
119
120static inline struct maildir_cached_session_state_data *
121cached_session_get_data(mailsession * s)
122{
123 return s->sess_data;
124}
125
126static inline mailsession * cached_session_get_ancestor(mailsession * s)
127{
128 return cached_session_get_data(s)->md_ancestor;
129}
130
131static inline struct maildir_session_state_data *
132cached_session_get_ancestor_data(mailsession * s)
133{
134 return cached_session_get_ancestor(s)->sess_data;
135}
136
137static inline struct maildir_session_state_data *
138get_session_ancestor_data(mailmessage * msg)
139{
140 return cached_session_get_ancestor_data(msg->msg_session);
141}
142
143static inline struct maildir *
144cached_session_get_maildir_session(mailsession * session)
145{
146 return cached_session_get_ancestor_data(session)->md_session;
147}
148
149static inline struct maildir * get_maildir_session(mailmessage * msg)
150{
151 return cached_session_get_maildir_session(msg->msg_session);
152}
153
154static int prefetch(mailmessage * msg_info)
155{
156 struct generic_message_t * msg;
157 int res;
158 struct maildir_msg_data * data;
159 char * filename;
160 int fd;
161 char * mapping;
162 struct maildir * md;
163
164 md = get_maildir_session(msg_info);
165
166 filename = maildir_message_get(md, msg_info->msg_uid);
167 if (filename == NULL) {
168 res = MAIL_ERROR_MEMORY;
169 goto err;
170 }
171
172 fd = open(filename, O_RDONLY);
173 free(filename);
174 if (fd == -1) {
175 res = MAIL_ERROR_FILE;
176 goto err;
177 }
178
179 mapping = mmap(NULL, msg_info->msg_size, PROT_READ, MAP_PRIVATE, fd, 0);
180 if (mapping == MAP_FAILED) {
181 res = MAIL_ERROR_FILE;
182 goto close;
183 }
184
185 data = malloc(sizeof(* data));
186 if (data == NULL) {
187 res = MAIL_ERROR_MEMORY;
188 goto unmap;
189 }
190
191 data->fd = fd;
192
193 msg = msg_info->msg_data;
194
195 msg->msg_data = data;
196 msg->msg_message = mapping;
197 msg->msg_length = msg_info->msg_size;
198
199 return MAIL_NO_ERROR;
200
201 unmap:
202 munmap(mapping, msg_info->msg_size);
203 close:
204 close(fd);
205 err:
206 return res;
207}
208
209static void prefetch_free(struct generic_message_t * msg)
210{
211 if (msg->msg_message != NULL) {
212 struct maildir_msg_data * data;
213
214 munmap(msg->msg_message, msg->msg_length);
215 msg->msg_message = NULL;
216 data = msg->msg_data;
217 close(data->fd);
218 free(data);
219 }
220}
221
222static int initialize(mailmessage * msg_info)
223{
224 struct generic_message_t * msg;
225 int r;
226
227 r = mailmessage_generic_initialize(msg_info);
228 if (r != MAIL_NO_ERROR)
229 return r;
230
231 msg = msg_info->msg_data;
232 msg->msg_prefetch = prefetch;
233 msg->msg_prefetch_free = prefetch_free;
234
235 return MAIL_NO_ERROR;
236}
237
238static void check(mailmessage * msg_info)
239{
240 int r;
241
242 if (msg_info->msg_flags != NULL) {
243 r = mail_flags_store_set(get_session_ancestor_data(msg_info)->md_flags_store, msg_info);
244
245 r = mail_flags_store_set(get_cached_session_data(msg_info)->md_flags_store, msg_info);
246 /* ignore errors */
247 }
248}
diff --git a/kmicromail/libetpan/generic/maildirdriver_cached_message.h b/kmicromail/libetpan/generic/maildirdriver_cached_message.h
new file mode 100644
index 0000000..399ecaa
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_cached_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIRDRIVER_CACHED_MESSAGE_H
37
38#define MAILDIRDRIVER_CACHED_MESSAGE_H
39
40#include <libetpan/maildirdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * maildir_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/maildirdriver_message.c b/kmicromail/libetpan/generic/maildirdriver_message.c
new file mode 100644
index 0000000..7cf9dd1
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_message.c
@@ -0,0 +1,199 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "maildirdriver_message.h"
37
38#include "mailmessage_tools.h"
39#include "maildirdriver.h"
40#include "maildir.h"
41#include "generic_cache.h"
42
43#include <unistd.h>
44#include <sys/mman.h>
45#include <sys/types.h>
46#include <sys/stat.h>
47#include <fcntl.h>
48#include <string.h>
49#include <stdlib.h>
50
51static int prefetch(mailmessage * msg_info);
52
53static void prefetch_free(struct generic_message_t * msg);
54
55static int initialize(mailmessage * msg_info);
56
57static void check(mailmessage * msg_info);
58
59static mailmessage_driver local_maildir_message_driver = {
60 .msg_name = "maildir",
61
62 .msg_initialize = initialize,
63 .msg_uninitialize = mailmessage_generic_uninitialize,
64
65 .msg_flush = mailmessage_generic_flush,
66 .msg_check = check,
67
68 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
69
70 .msg_fetch = mailmessage_generic_fetch,
71 .msg_fetch_header = mailmessage_generic_fetch_header,
72 .msg_fetch_body = mailmessage_generic_fetch_header,
73 .msg_fetch_size = NULL,
74 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
75 .msg_fetch_section = mailmessage_generic_fetch_section,
76 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
77 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
78 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
79 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
80
81 .msg_get_flags = NULL,
82};
83
84mailmessage_driver * maildir_message_driver = &local_maildir_message_driver;
85
86struct maildir_msg_data {
87 int fd;
88};
89
90static inline struct maildir_session_state_data *
91get_session_data(mailmessage * msg)
92{
93 return msg->msg_session->sess_data;
94}
95
96static struct maildir * get_maildir_session(mailmessage * msg)
97{
98 return get_session_data(msg)->md_session;
99}
100
101static int prefetch(mailmessage * msg_info)
102{
103 struct generic_message_t * msg;
104 int res;
105 struct maildir_msg_data * data;
106 char * filename;
107 int fd;
108 char * mapping;
109 struct maildir * md;
110
111 md = get_maildir_session(msg_info);
112
113 if (msg_info->msg_uid == NULL) {
114 res = MAIL_ERROR_INVAL;
115 goto err;
116 }
117
118 filename = maildir_message_get(md, msg_info->msg_uid);
119 if (filename == NULL) {
120 res = MAIL_ERROR_MEMORY;
121 goto err;
122 }
123
124 fd = open(filename, O_RDONLY);
125 free(filename);
126 if (fd == -1) {
127 res = MAIL_ERROR_FILE;
128 goto err;
129 }
130
131 mapping = mmap(NULL, msg_info->msg_size, PROT_READ, MAP_PRIVATE, fd, 0);
132 if (mapping == MAP_FAILED) {
133 res = MAIL_ERROR_FILE;
134 goto close;
135 }
136
137 data = malloc(sizeof(* data));
138 if (data == NULL) {
139 res = MAIL_ERROR_MEMORY;
140 goto unmap;
141 }
142
143 data->fd = fd;
144
145 msg = msg_info->msg_data;
146
147 msg->msg_data = data;
148 msg->msg_message = mapping;
149 msg->msg_length = msg_info->msg_size;
150
151 return MAIL_NO_ERROR;
152
153 unmap:
154 munmap(mapping, msg_info->msg_size);
155 close:
156 close(fd);
157 err:
158 return res;
159}
160
161static void prefetch_free(struct generic_message_t * msg)
162{
163 if (msg->msg_message != NULL) {
164 struct maildir_msg_data * data;
165
166 munmap(msg->msg_message, msg->msg_length);
167 msg->msg_message = NULL;
168 data = msg->msg_data;
169 close(data->fd);
170 free(data);
171 }
172}
173
174static int initialize(mailmessage * msg_info)
175{
176 struct generic_message_t * msg;
177 int r;
178
179 r = mailmessage_generic_initialize(msg_info);
180 if (r != MAIL_NO_ERROR)
181 return r;
182
183 msg = msg_info->msg_data;
184 msg->msg_prefetch = prefetch;
185 msg->msg_prefetch_free = prefetch_free;
186
187 return MAIL_NO_ERROR;
188}
189
190static void check(mailmessage * msg_info)
191{
192 int r;
193
194 if (msg_info->msg_flags != NULL) {
195 r = mail_flags_store_set(get_session_data(msg_info)->md_flags_store,
196 msg_info);
197 /* ignore errors */
198 }
199}
diff --git a/kmicromail/libetpan/generic/maildirdriver_message.h b/kmicromail/libetpan/generic/maildirdriver_message.h
new file mode 100644
index 0000000..cb378bc
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIRDRIVER_MESSAGE_H
37
38#define MAILDIRDRIVER_MESSAGE_H
39
40#include <libetpan/maildirdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * maildir_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/maildirdriver_tools.c b/kmicromail/libetpan/generic/maildirdriver_tools.c
new file mode 100644
index 0000000..f3e21e4
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_tools.c
@@ -0,0 +1,195 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailmessage.h"
37#include "maildirdriver_tools.h"
38#include "maildir.h"
39#include "generic_cache.h"
40#include <sys/types.h>
41#include <sys/stat.h>
42#include <stdlib.h>
43#include <string.h>
44
45int maildirdriver_maildir_error_to_mail_error(int error)
46{
47 switch (error) {
48 case MAILDIR_NO_ERROR:
49 return MAIL_NO_ERROR;
50
51 case MAILDIR_ERROR_CREATE:
52 return MAIL_ERROR_FILE;
53
54 case MAILDIR_ERROR_DIRECTORY:
55 return MAIL_ERROR_FILE;
56
57 case MAILDIR_ERROR_MEMORY:
58 return MAIL_ERROR_MEMORY;
59
60 case MAILDIR_ERROR_FILE:
61 return MAIL_ERROR_FILE;
62
63 case MAILDIR_ERROR_NOT_FOUND:
64 return MAIL_ERROR_MSG_NOT_FOUND;
65
66 default:
67 return MAIL_ERROR_INVAL;
68 }
69}
70
71
72
73uint32_t maildirdriver_maildir_flags_to_flags(uint32_t md_flags)
74{
75 uint32_t flags;
76
77 flags = 0;
78 if ((md_flags & MAILDIR_FLAG_NEW) != 0)
79 flags |= MAIL_FLAG_NEW;
80
81 if ((md_flags & MAILDIR_FLAG_SEEN) != 0)
82 flags |= MAIL_FLAG_SEEN;
83
84 if ((md_flags & MAILDIR_FLAG_REPLIED) != 0)
85 flags |= MAIL_FLAG_ANSWERED;
86
87 if ((md_flags & MAILDIR_FLAG_FLAGGED) != 0)
88 flags |= MAIL_FLAG_FLAGGED;
89
90 if ((md_flags & MAILDIR_FLAG_TRASHED) != 0)
91 flags |= MAIL_FLAG_DELETED;
92
93 return flags;
94}
95
96uint32_t maildirdriver_flags_to_maildir_flags(uint32_t flags)
97{
98 uint32_t md_flags;
99
100 md_flags = 0;
101 if ((flags & MAIL_FLAG_NEW) != 0)
102 md_flags |= MAILDIR_FLAG_NEW;
103
104 if ((flags & MAIL_FLAG_SEEN) != 0)
105 md_flags |= MAILDIR_FLAG_SEEN;
106
107 if ((flags & MAIL_FLAG_ANSWERED) != 0)
108 md_flags |= MAILDIR_FLAG_REPLIED;
109
110 if ((flags & MAIL_FLAG_FLAGGED) != 0)
111 md_flags |= MAILDIR_FLAG_FLAGGED;
112
113 if ((flags & MAIL_FLAG_DELETED) != 0)
114 md_flags |= MAILDIR_FLAG_TRASHED;
115
116 return md_flags;
117}
118
119
120int maildir_get_messages_list(mailsession * session, struct maildir * md,
121 mailmessage_driver * message_driver,
122 struct mailmessage_list ** result)
123{
124 unsigned int i;
125 struct mailmessage_list * env_list;
126 int r;
127 carray * tab;
128 int res;
129
130 tab = carray_new(128);
131 if (tab == NULL) {
132 res = MAIL_ERROR_MEMORY;
133 goto err;
134 }
135
136 for(i = 0 ; i < carray_count(md->mdir_msg_list) ; i++) {
137 struct maildir_msg * md_msg;
138 mailmessage * msg;
139 char * filename;
140 struct stat stat_info;
141
142 md_msg = carray_get(md->mdir_msg_list, i);
143
144 filename = maildir_message_get(md, md_msg->msg_uid);
145 r = stat(filename, &stat_info);
146 free(filename);
147 if (r < 0)
148 continue;
149
150 msg = mailmessage_new();
151 if (msg == NULL) {
152 res = MAIL_ERROR_MEMORY;
153 goto free_list;
154 }
155
156 r = mailmessage_init(msg, session, message_driver,
157 i + 1, stat_info.st_size);
158 if (r != MAIL_NO_ERROR) {
159 mailmessage_free(msg);
160 res = r;
161 goto free_list;
162 }
163
164 msg->msg_uid = strdup(md_msg->msg_uid);
165 if (msg->msg_uid == NULL) {
166 mailmessage_free(msg);
167 res = MAIL_ERROR_MEMORY;
168 goto free_list;
169 }
170
171 r = carray_add(tab, msg, NULL);
172 if (r < 0) {
173 mailmessage_free(msg);
174 res = MAIL_ERROR_MEMORY;
175 goto free_list;
176 }
177 }
178
179 env_list = mailmessage_list_new(tab);
180 if (env_list == NULL) {
181 res = MAIL_ERROR_MEMORY;
182 goto free_list;
183 }
184
185 * result = env_list;
186
187 return MAIL_NO_ERROR;
188
189 free_list:
190 for(i = 0 ; i < carray_count(tab) ; i ++)
191 mailmessage_free(carray_get(tab, i));
192 carray_free(tab);
193 err:
194 return res;
195}
diff --git a/kmicromail/libetpan/generic/maildirdriver_tools.h b/kmicromail/libetpan/generic/maildirdriver_tools.h
new file mode 100644
index 0000000..3c8931f
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_tools.h
@@ -0,0 +1,53 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIRDRIVER_TOOLS_H
37
38#define MAILDIRDRIVER_TOOLS_H
39
40#include "maildriver_types.h"
41#include "maildir.h"
42
43int maildirdriver_maildir_error_to_mail_error(int error);
44
45uint32_t maildirdriver_maildir_flags_to_flags(uint32_t md_flags);
46
47uint32_t maildirdriver_flags_to_maildir_flags(uint32_t flags);
48
49int maildir_get_messages_list(mailsession * session, struct maildir * md,
50 mailmessage_driver * message_driver,
51 struct mailmessage_list ** result);
52
53#endif
diff --git a/kmicromail/libetpan/generic/maildirdriver_types.h b/kmicromail/libetpan/generic/maildirdriver_types.h
new file mode 100644
index 0000000..cb3661f
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_types.h
@@ -0,0 +1,96 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIRDRIVER_TYPES_H
37
38#define MAILDIRDRIVER_TYPES_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/maildriver_types.h>
43#include <libetpan/maildir.h>
44#include <libetpan/generic_cache_types.h>
45#include <libetpan/mailstorage_types.h>
46
47#ifdef __cplusplus
48extern "C" {
49#endif
50
51struct maildir_session_state_data {
52 struct maildir * md_session;
53 struct mail_flags_store * md_flags_store;
54};
55
56enum {
57 MAILDIRDRIVER_CACHED_SET_CACHE_DIRECTORY = 1,
58 MAILDIRDRIVER_CACHED_SET_FLAGS_DIRECTORY,
59};
60
61struct maildir_cached_session_state_data {
62 mailsession * md_ancestor;
63 char * md_quoted_mb;
64 struct mail_flags_store * md_flags_store;
65 char md_cache_directory[PATH_MAX];
66 char md_flags_directory[PATH_MAX];
67};
68
69/* maildir storage */
70
71/*
72 maildir_mailstorage is the state data specific to the maildir storage.
73
74 - pathname is the path of the maildir storage.
75
76 - cached if this value is != 0, a persistant cache will be
77 stored on local system.
78
79 - cache_directory is the location of the cache.
80
81 - flags_directory is the location of the flags.
82*/
83
84struct maildir_mailstorage {
85 char * md_pathname;
86
87 int md_cached;
88 char * md_cache_directory;
89 char * md_flags_directory;
90};
91
92#ifdef __cplusplus
93}
94#endif
95
96#endif
diff --git a/kmicromail/libetpan/generic/maildirstorage.c b/kmicromail/libetpan/generic/maildirstorage.c
new file mode 100644
index 0000000..7e6b461
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirstorage.c
@@ -0,0 +1,192 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailstorage.h"
37
38#include "mail.h"
39#include "mailmessage.h"
40#include "maildirdriver.h"
41#include "maildirdriver_cached.h"
42#include "maildriver.h"
43
44#include <stdlib.h>
45#include <string.h>
46
47/* maildir storage */
48
49static int maildir_mailstorage_connect(struct mailstorage * storage);
50static int
51maildir_mailstorage_get_folder_session(struct mailstorage * storage,
52 char * pathname, mailsession ** result);
53static void maildir_mailstorage_uninitialize(struct mailstorage * storage);
54
55static mailstorage_driver maildir_mailstorage_driver = {
56 .sto_name = "maildir",
57 .sto_connect = maildir_mailstorage_connect,
58 .sto_get_folder_session = maildir_mailstorage_get_folder_session,
59 .sto_uninitialize = maildir_mailstorage_uninitialize,
60};
61
62int maildir_mailstorage_init(struct mailstorage * storage,
63 char * md_pathname, int md_cached,
64 char * md_cache_directory, char * md_flags_directory)
65{
66 struct maildir_mailstorage * maildir_storage;
67
68 maildir_storage = malloc(sizeof(struct maildir_mailstorage));
69 if (maildir_storage == NULL)
70 goto err;
71
72 maildir_storage->md_pathname = strdup(md_pathname);
73 if (maildir_storage->md_pathname == NULL)
74 goto free;
75
76 maildir_storage->md_cached = md_cached;
77
78 if (md_cached && (md_cache_directory != NULL) &&
79 (md_flags_directory != NULL)) {
80 maildir_storage->md_cache_directory = strdup(md_cache_directory);
81 if (maildir_storage->md_cache_directory == NULL)
82 goto free_pathname;
83
84 maildir_storage->md_flags_directory = strdup(md_flags_directory);
85 if (maildir_storage->md_flags_directory == NULL)
86 goto free_cache_directory;
87 }
88 else {
89 maildir_storage->md_cached = FALSE;
90 maildir_storage->md_cache_directory = NULL;
91 maildir_storage->md_flags_directory = NULL;
92 }
93
94 storage->sto_data = maildir_storage;
95 storage->sto_driver = &maildir_mailstorage_driver;
96
97 return MAIL_NO_ERROR;
98
99 free_cache_directory:
100 free(maildir_storage->md_cache_directory);
101 free_pathname:
102 free(maildir_storage->md_pathname);
103 free:
104 free(maildir_storage);
105 err:
106 return MAIL_ERROR_MEMORY;
107}
108
109static void maildir_mailstorage_uninitialize(struct mailstorage * storage)
110{
111 struct maildir_mailstorage * maildir_storage;
112
113 maildir_storage = storage->sto_data;
114 if (maildir_storage->md_flags_directory != NULL)
115 free(maildir_storage->md_flags_directory);
116 if (maildir_storage->md_cache_directory != NULL)
117 free(maildir_storage->md_cache_directory);
118 free(maildir_storage->md_pathname);
119 free(maildir_storage);
120
121 storage->sto_data = NULL;
122}
123
124static int maildir_mailstorage_connect(struct mailstorage * storage)
125{
126 struct maildir_mailstorage * maildir_storage;
127 mailsession_driver * driver;
128 int r;
129 int res;
130 mailsession * session;
131
132 maildir_storage = storage->sto_data;
133
134 if (maildir_storage->md_cached)
135 driver = maildir_cached_session_driver;
136 else
137 driver = maildir_session_driver;
138
139 session = mailsession_new(driver);
140 if (session == NULL) {
141 res = MAIL_ERROR_MEMORY;
142 goto err;
143 }
144
145 if (maildir_storage->md_cached) {
146 r = mailsession_parameters(session,
147 MAILDIRDRIVER_CACHED_SET_CACHE_DIRECTORY,
148 maildir_storage->md_cache_directory);
149 if (r != MAIL_NO_ERROR) {
150 res = r;
151 goto free;
152 }
153
154 r = mailsession_parameters(session,
155 MAILDIRDRIVER_CACHED_SET_FLAGS_DIRECTORY,
156 maildir_storage->md_flags_directory);
157 if (r != MAIL_NO_ERROR) {
158 res = r;
159 goto free;
160 }
161 }
162
163 r = mailsession_connect_path(session, maildir_storage->md_pathname);
164 switch (r) {
165 case MAIL_NO_ERROR_NON_AUTHENTICATED:
166 case MAIL_NO_ERROR_AUTHENTICATED:
167 case MAIL_NO_ERROR:
168 break;
169 default:
170 res = r;
171 goto free;
172 }
173
174 storage->sto_session = session;
175
176 return MAIL_NO_ERROR;
177
178 free:
179 mailsession_free(session);
180 err:
181 return res;
182}
183
184static int
185maildir_mailstorage_get_folder_session(struct mailstorage * storage,
186 char * pathname, mailsession ** result)
187{
188 * result = storage->sto_session;
189
190 return MAIL_NO_ERROR;
191}
192
diff --git a/kmicromail/libetpan/generic/maildirstorage.h b/kmicromail/libetpan/generic/maildirstorage.h
new file mode 100644
index 0000000..d17ea2c
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirstorage.h
@@ -0,0 +1,69 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIRSTORAGE_H
37
38#define MAILDIRSTORAGE_H
39
40#include <libetpan/maildirdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 maildir_mailstorage_init is the constructor for a mbox storage.
48
49 @param storage this is the storage to initialize.
50
51 @param pathname is the directory that contains the mailbox.
52
53 @param cached if this value is != 0, a persistant cache will be
54 stored on local system.
55
56 @param cache_directory is the location of the cache
57
58 @param flags_directory is the location of the flags
59*/
60
61int maildir_mailstorage_init(struct mailstorage * storage,
62 char * md_pathname, int md_cached,
63 char * md_cache_directory, char * md_flags_directory);
64
65#ifdef __cplusplus
66}
67#endif
68
69#endif
diff --git a/kmicromail/libetpan/generic/maildriver.c b/kmicromail/libetpan/generic/maildriver.c
new file mode 100644
index 0000000..01e3e34
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver.c
@@ -0,0 +1,373 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "maildriver.h"
37#include <ctype.h>
38#include <string.h>
39#include <stdlib.h>
40
41/* *********************************************************************** */
42/* mail session */
43
44mailsession * mailsession_new(mailsession_driver * sess_driver)
45{
46 mailsession * session;
47 int r;
48
49 session = malloc(sizeof(* session));
50
51 session->sess_data = NULL;
52
53 if (sess_driver->sess_initialize != NULL) {
54 r = sess_driver->sess_initialize(session);
55 if (r != MAIL_NO_ERROR)
56 goto free;
57 }
58
59 session->sess_driver = sess_driver;
60
61 return session;
62
63 free:
64 free(session);
65 return NULL;
66}
67
68void mailsession_free(mailsession * session)
69{
70 if (session->sess_driver->sess_uninitialize != NULL)
71 session->sess_driver->sess_uninitialize(session);
72 free(session);
73}
74
75int mailsession_parameters(mailsession * session,
76 int id, void * value)
77{
78 if (session->sess_driver->sess_parameters == NULL)
79 return MAIL_ERROR_NOT_IMPLEMENTED;
80
81 return session->sess_driver->sess_parameters(session, id, value);
82}
83
84int mailsession_connect_stream(mailsession * session, mailstream * s)
85{
86 if (session->sess_driver->sess_connect_stream == NULL)
87 return MAIL_ERROR_NOT_IMPLEMENTED;
88
89 return session->sess_driver->sess_connect_stream(session, s);
90}
91
92int mailsession_connect_path(mailsession * session, char * path)
93{
94 if (session->sess_driver->sess_connect_path == NULL)
95 return MAIL_ERROR_NOT_IMPLEMENTED;
96
97 return session->sess_driver->sess_connect_path(session, path);
98}
99
100int mailsession_starttls(mailsession * session)
101{
102 if (session->sess_driver->sess_starttls == NULL)
103 return MAIL_ERROR_NOT_IMPLEMENTED;
104
105 return session->sess_driver->sess_starttls(session);
106}
107
108int mailsession_login(mailsession * session,
109 char * userid, char * password)
110{
111 if (session->sess_driver->sess_login == NULL)
112 return MAIL_ERROR_NOT_IMPLEMENTED;
113
114 return session->sess_driver->sess_login(session, userid, password);
115}
116
117int mailsession_logout(mailsession * session)
118{
119 if (session->sess_driver->sess_logout == NULL)
120 return MAIL_ERROR_NOT_IMPLEMENTED;
121
122 return session->sess_driver->sess_logout(session);
123}
124
125int mailsession_noop(mailsession * session)
126{
127 if (session->sess_driver->sess_noop == NULL)
128 return MAIL_ERROR_NOT_IMPLEMENTED;
129
130 return session->sess_driver->sess_noop(session);
131}
132
133/* folders operations */
134
135int mailsession_build_folder_name(mailsession * session, char * mb,
136 char * name, char ** result)
137{
138 if (session->sess_driver->sess_build_folder_name == NULL)
139 return MAIL_ERROR_NOT_IMPLEMENTED;
140
141 return session->sess_driver->sess_build_folder_name(session,
142 mb, name, result);
143}
144
145int mailsession_create_folder(mailsession * session, char * mb)
146{
147 if (session->sess_driver->sess_create_folder == NULL)
148 return MAIL_ERROR_NOT_IMPLEMENTED;
149
150 return session->sess_driver->sess_create_folder(session, mb);
151}
152
153int mailsession_delete_folder(mailsession * session, char * mb)
154{
155 if (session->sess_driver->sess_delete_folder == NULL)
156 return MAIL_ERROR_NOT_IMPLEMENTED;
157
158 return session->sess_driver->sess_delete_folder(session, mb);
159}
160
161int mailsession_rename_folder(mailsession * session,
162 char * mb, char * new_name)
163{
164 if (session->sess_driver->sess_rename_folder == NULL)
165 return MAIL_ERROR_NOT_IMPLEMENTED;
166
167 return session->sess_driver->sess_rename_folder(session, mb, new_name);
168}
169
170int mailsession_check_folder(mailsession * session)
171{
172 if (session->sess_driver->sess_check_folder == NULL)
173 return MAIL_ERROR_NOT_IMPLEMENTED;
174
175 return session->sess_driver->sess_check_folder(session);
176}
177
178int mailsession_examine_folder(mailsession * session, char * mb)
179{
180 if (session->sess_driver->sess_examine_folder == NULL)
181 return MAIL_ERROR_NOT_IMPLEMENTED;
182
183 return session->sess_driver->sess_examine_folder(session, mb);
184}
185
186int mailsession_select_folder(mailsession * session, char * mb)
187{
188 if (session->sess_driver->sess_select_folder == NULL)
189 return MAIL_ERROR_NOT_IMPLEMENTED;
190
191 return session->sess_driver->sess_select_folder(session, mb);
192}
193
194int mailsession_expunge_folder(mailsession * session)
195{
196 if (session->sess_driver->sess_expunge_folder == NULL)
197 return MAIL_ERROR_NOT_IMPLEMENTED;
198
199 return session->sess_driver->sess_expunge_folder(session);
200}
201
202int mailsession_status_folder(mailsession * session, char * mb,
203 uint32_t * result_messages, uint32_t * result_recent,
204 uint32_t * result_unseen)
205{
206 if (session->sess_driver->sess_status_folder == NULL)
207 return MAIL_ERROR_NOT_IMPLEMENTED;
208
209 return session->sess_driver->sess_status_folder(session, mb,
210 result_messages, result_recent, result_unseen);
211}
212
213int mailsession_messages_number(mailsession * session, char * mb,
214 uint32_t * result)
215{
216 if (session->sess_driver->sess_messages_number == NULL)
217 return MAIL_ERROR_NOT_IMPLEMENTED;
218
219 return session->sess_driver->sess_messages_number(session, mb, result);
220}
221
222int mailsession_recent_number(mailsession * session, char * mb,
223 uint32_t * result)
224{
225 if (session->sess_driver->sess_recent_number == NULL)
226 return MAIL_ERROR_NOT_IMPLEMENTED;
227
228 return session->sess_driver->sess_recent_number(session, mb, result);
229}
230
231int mailsession_unseen_number(mailsession * session, char * mb,
232 uint32_t * result)
233{
234 if (session->sess_driver->sess_unseen_number == NULL)
235 return MAIL_ERROR_NOT_IMPLEMENTED;
236
237 return session->sess_driver->sess_recent_number(session, mb, result);
238}
239
240int mailsession_list_folders(mailsession * session, char * mb,
241 struct mail_list ** result)
242{
243 if (session->sess_driver->sess_list_folders == NULL)
244 return MAIL_ERROR_NOT_IMPLEMENTED;
245
246 return session->sess_driver->sess_list_folders(session, mb, result);
247}
248
249int mailsession_lsub_folders(mailsession * session, char * mb,
250 struct mail_list ** result)
251{
252 if (session->sess_driver->sess_lsub_folders == NULL)
253 return MAIL_ERROR_NOT_IMPLEMENTED;
254
255 return session->sess_driver->sess_lsub_folders(session, mb, result);
256}
257
258int mailsession_subscribe_folder(mailsession * session, char * mb)
259{
260 if (session->sess_driver->sess_subscribe_folder == NULL)
261 return MAIL_ERROR_NOT_IMPLEMENTED;
262
263 return session->sess_driver->sess_subscribe_folder(session, mb);
264}
265
266int mailsession_unsubscribe_folder(mailsession * session, char * mb)
267{
268 if (session->sess_driver->sess_unsubscribe_folder == NULL)
269 return MAIL_ERROR_NOT_IMPLEMENTED;
270
271 return session->sess_driver->sess_unsubscribe_folder(session, mb);
272}
273
274/* message */
275
276int mailsession_append_message(mailsession * session,
277 char * message, size_t size)
278{
279 if (session->sess_driver->sess_append_message == NULL)
280 return MAIL_ERROR_NOT_IMPLEMENTED;
281
282 return session->sess_driver->sess_append_message(session, message, size);
283}
284
285int mailsession_copy_message(mailsession * session,
286 uint32_t num, char * mb)
287{
288 if (session->sess_driver->sess_copy_message == NULL)
289 return MAIL_ERROR_NOT_IMPLEMENTED;
290
291 return session->sess_driver->sess_copy_message(session, num, mb);
292}
293
294int mailsession_move_message(mailsession * session,
295 uint32_t num, char * mb)
296{
297 if (session->sess_driver->sess_move_message == NULL) {
298 int r;
299
300 if ((session->sess_driver->sess_copy_message == NULL) &&
301 (session->sess_driver->sess_remove_message == NULL))
302 return MAIL_ERROR_NOT_IMPLEMENTED;
303
304 r = mailsession_copy_message(session, num, mb);
305 if (r != MAIL_NO_ERROR)
306 return r;
307
308 r = mailsession_remove_message(session, num);
309 if (r != MAIL_NO_ERROR)
310 return r;
311
312 return MAIL_NO_ERROR;
313 }
314
315 return session->sess_driver->sess_move_message(session, num, mb);
316}
317
318int mailsession_get_envelopes_list(mailsession * session,
319 struct mailmessage_list * env_list)
320{
321 if (session->sess_driver->sess_get_envelopes_list == NULL)
322 return MAIL_ERROR_NOT_IMPLEMENTED;
323
324 return session->sess_driver->sess_get_envelopes_list(session, env_list);
325}
326
327int mailsession_get_messages_list(mailsession * session,
328 struct mailmessage_list ** result)
329{
330 if (session->sess_driver->sess_get_messages_list == NULL)
331 return MAIL_ERROR_NOT_IMPLEMENTED;
332
333 return session->sess_driver->sess_get_messages_list(session, result);
334}
335
336int mailsession_remove_message(mailsession * session, uint32_t num)
337{
338 if (session->sess_driver->sess_remove_message == NULL)
339 return MAIL_ERROR_NOT_IMPLEMENTED;
340
341 return session->sess_driver->sess_remove_message(session, num);
342}
343
344#if 0
345int mailsession_search_messages(mailsession * session, char * charset,
346 struct mail_search_key * key,
347 struct mail_search_result ** result)
348{
349 if (session->sess_driver->sess_search_messages == NULL)
350 return MAIL_ERROR_NOT_IMPLEMENTED;
351
352 return session->sess_driver->sess_search_messages(session,
353 charset, key, result);
354}
355#endif
356
357int mailsession_get_message(mailsession * session,
358 uint32_t num, mailmessage ** result)
359{
360 if (session->sess_driver->sess_get_message == NULL)
361 return MAIL_ERROR_NOT_IMPLEMENTED;
362
363 return session->sess_driver->sess_get_message(session, num, result);
364}
365
366int mailsession_get_message_by_uid(mailsession * session,
367 const char * uid, mailmessage ** result)
368{
369 if (session->sess_driver->sess_get_message_by_uid == NULL)
370 return MAIL_ERROR_NOT_IMPLEMENTED;
371
372 return session->sess_driver->sess_get_message_by_uid(session, uid, result);
373}
diff --git a/kmicromail/libetpan/generic/maildriver.h b/kmicromail/libetpan/generic/maildriver.h
new file mode 100644
index 0000000..7da9aea
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver.h
@@ -0,0 +1,543 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDRIVER_H
37
38#define MAILDRIVER_H
39
40#include <libetpan/maildriver_types.h>
41#include <libetpan/maildriver_types_helper.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47/* mailsession */
48
49/*
50 mailsession_new creates a new session, using the given driver
51
52 @return the created session is returned
53*/
54
55mailsession * mailsession_new(mailsession_driver * sess_driver);
56
57/*
58 mailsession_free release the memory used by the session
59*/
60
61void mailsession_free(mailsession * session);
62
63/*
64 mailsession_parameters is used to make calls specific to the driver
65
66 @param id is the command to send to the driver,
67 usually, commands can be found in the header of the driver
68
69 @param value is the parameter of the specific call
70
71 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
72 on error
73*/
74
75int mailsession_parameters(mailsession * session,
76 int id, void * value);
77
78/*
79 There are drivers of two kinds : stream drivers (driver that connects
80 to servers through TCP or other means of connection) and file drivers
81 (driver that are based on filesystem)
82
83 The following function can only be used by stream drivers.
84 mailsession_connect_stream connects a stream to the session
85
86 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
87 on error
88*/
89
90int mailsession_connect_stream(mailsession * session, mailstream * s);
91
92/*
93 The following function can only be used by file drivers.
94 mailsession_connect_path selects the main path of the session
95
96 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
97 on error
98*/
99
100int mailsession_connect_path(mailsession * session, char * path);
101
102/*
103 NOTE: works only on stream drivers
104
105 mailsession_starttls switches the current connection to TLS (secure layer)
106
107 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
108 on error
109*/
110
111int mailsession_starttls(mailsession * session);
112
113/*
114 mailsession_login notifies the login and the password to authenticate
115 to the session
116
117 @param userid the given string is only needed at this function call
118 (it will be duplicated if necessary)
119 @param password the given string is only needed at this function call
120 (it will be duplicated if necessary)
121
122 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
123 on error
124*/
125
126int mailsession_login(mailsession * session,
127 char * userid, char * password);
128
129/*
130 NOTE: this function doesn't often work on filsystem drivers
131
132 mailsession_logout deconnects the session and closes the stream.
133
134 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
135 on error
136*/
137
138int mailsession_logout(mailsession * session);
139
140/*
141 mailsession_noop does no operation on the session, but it can be
142 used to poll for the status of the connection.
143
144 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
145 on error
146*/
147
148int mailsession_noop(mailsession * session);
149
150/*
151 NOTE: driver's specific should be used
152
153 mailsession_build_folder_name will return an allocated string with
154 that contains the complete path of the folder to create
155
156 @param session the sesion
157 @param mb is the parent mailbox
158 @param name is the name of the folder to create
159 @param result the complete path of the folder to create will be
160 stored in (* result), this name have to be freed with free()
161
162 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
163 on error
164*/
165
166int mailsession_build_folder_name(mailsession * session, char * mb,
167 char * name, char ** result);
168
169/*
170 NOTE: driver's specific should be used
171
172 mailsession_create_folder creates the folder that corresponds to the
173 given name
174
175 @param session the session
176 @param mb is the name of the mailbox
177
178 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
179 on error
180*/
181
182int mailsession_create_folder(mailsession * session, char * mb);
183
184
185/*
186 NOTE: driver's specific should be used
187
188 mailsession_delete_folder deletes the folder that corresponds to the
189 given name
190
191 @param session the session
192 @param mb is the name of the mailbox
193
194 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
195 on error
196*/
197
198int mailsession_delete_folder(mailsession * session, char * mb);
199
200
201/*
202 mailsession_rename_folder changes the name of the folder
203
204 @param session the session
205 @param mb is the name of the mailbox whose name has to be changed
206 @param new_name is the destination name (the parent
207 of the new folder folder can be other)
208
209 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
210 on error
211*/
212
213int mailsession_rename_folder(mailsession * session,
214 char * mb, char * new_name);
215
216/*
217 mailsession_check_folder makes a checkpoint of the session
218
219 @param session the session
220
221 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
222 on error
223*/
224
225int mailsession_check_folder(mailsession * session);
226
227
228/*
229 NOTE: this function is not implemented in most drivers
230
231 mailsession_examine_folder selects a mailbox as readonly
232
233 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
234 on error
235*/
236
237int mailsession_examine_folder(mailsession * session, char * mb);
238
239
240/*
241 mailsession_select_folder selects a mailbox
242
243 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
244 on error
245*/
246
247int mailsession_select_folder(mailsession * session, char * mb);
248
249
250/*
251 mailsession_expunge_folder deletes all messages marked \Deleted
252
253 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
254 on error
255*/
256
257int mailsession_expunge_folder(mailsession * session);
258
259
260/*
261 mailsession_status_folder queries the status of the folder
262 (number of messages, number of recent messages, number of unseen messages)
263
264 @param session the session
265 @param mb mailbox to query
266 @param result_messages the number of messages is stored
267 in (* result_messages)
268 @param result_recent the number of messages is stored
269 in (* result_recent)
270 @param result_unseen the number of messages is stored
271 in (* result_unseen)
272
273 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
274 on error
275*/
276
277int mailsession_status_folder(mailsession * session, char * mb,
278 uint32_t * result_messages, uint32_t * result_recent,
279 uint32_t * result_unseen);
280
281
282/*
283 mailsession_messages_number queries the number of messages in the folder
284
285 @param session the session
286 @param mb mailbox to query
287 @param result the number of messages is stored in (* result)
288
289 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
290 on error
291*/
292
293int mailsession_messages_number(mailsession * session, char * mb,
294 uint32_t * result);
295
296/*
297 mailsession_recent_number queries the number of recent messages in the folder
298
299 @param session the session
300 @param mb mailbox to query
301 @param result the number of recent messages is stored in (* result)
302
303 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
304 on error
305*/
306
307int mailsession_recent_number(mailsession * session,
308 char * mb, uint32_t * result);
309
310/*
311 mailsession_unseen_number queries the number of unseen messages in the folder
312
313 @param session the session
314 @param mb mailbox to query
315 @param result the number of unseen messages is stored in (* result)
316
317 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
318 on error
319*/
320
321int mailsession_unseen_number(mailsession * session, char * mb,
322 uint32_t * result);
323
324/*
325 NOTE: driver's specific should be used
326
327 mailsession_list_folders returns the list of all sub-mailboxes
328 of the given mailbox
329
330 @param session the session
331 @param mb the mailbox
332 @param result list of mailboxes if stored in (* result),
333 this structure have to be freed with mail_list_free()
334
335 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
336 on error
337*/
338
339int mailsession_list_folders(mailsession * session, char * mb,
340 struct mail_list ** result);
341
342/*
343 NOTE: driver's specific should be used
344
345 mailsession_lsub_folders returns the list of subscribed
346 sub-mailboxes of the given mailbox
347
348 @param session the session
349 @param mb the mailbox
350 @param result list of mailboxes if stored in (* result),
351 this structure have to be freed with mail_list_free()
352
353 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
354 on error
355*/
356
357int mailsession_lsub_folders(mailsession * session, char * mb,
358 struct mail_list ** result);
359
360/*
361 NOTE: driver's specific should be used
362
363 mailsession_subscribe_folder subscribes to the given mailbox
364
365 @param session the session
366 @param mb the mailbox
367
368 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
369 on error
370*/
371
372int mailsession_subscribe_folder(mailsession * session, char * mb);
373
374/*
375 NOTE: driver's specific should be used
376
377 mailsession_unsubscribe_folder unsubscribes to the given mailbox
378
379 @param session the session
380 @param mb the mailbox
381
382 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
383 on error
384*/
385
386int mailsession_unsubscribe_folder(mailsession * session, char * mb);
387
388/*
389 mailsession_append_message adds a RFC 2822 message to the current
390 given mailbox
391
392 @param session the session
393 @param message is a string that contains the RFC 2822 message
394 @param size this is the size of the message
395
396 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
397 on error
398*/
399
400int mailsession_append_message(mailsession * session,
401 char * message, size_t size);
402
403/*
404 NOTE: some drivers does not implement this
405
406 mailsession_copy_message copies a message whose number is given to
407 a given mailbox. The mailbox must be accessible from the same session.
408
409 @param session the session
410 @param num the message number
411 @param mb the destination mailbox
412
413 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
414 on error
415*/
416
417int mailsession_copy_message(mailsession * session,
418 uint32_t num, char * mb);
419
420/*
421 NOTE: some drivers does not implement this
422
423 mailsession_move_message copies a message whose number is given to
424 a given mailbox. The mailbox must be accessible from the same session.
425
426 @param session the session
427 @param num the message number
428 @param mb the destination mailbox
429
430 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
431 on error
432*/
433
434int mailsession_move_message(mailsession * session,
435 uint32_t num, char * mb);
436
437/*
438 mailsession_get_messages_list returns the list of message numbers
439 of the current mailbox.
440
441 @param session the session
442 @param result the list of message numbers will be stored in (* result),
443 this structure have to be freed with mailmessage_list_free()
444
445 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
446 on error
447*/
448
449int mailsession_get_messages_list(mailsession * session,
450 struct mailmessage_list ** result);
451
452/*
453 mailsession_get_envelopes_list fills the parsed fields in the
454 mailmessage structures of the mailmessage_list.
455
456 @param session the session
457 @param result this is the list of mailmessage structures
458
459 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
460 on error
461*/
462
463int mailsession_get_envelopes_list(mailsession * session,
464 struct mailmessage_list * result);
465
466/*
467 NOTE: some drivers does not implement this
468
469 mailsession_remove_message removes the given message from the mailbox.
470 The message is permanently deleted.
471
472 @param session the session
473 @param num is the message number
474
475 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
476 on error
477*/
478
479int mailsession_remove_message(mailsession * session, uint32_t num);
480
481
482/*
483 NOTE: this function is not implemented in most drivers
484
485 mailsession_search_message returns a list of message numbers that
486 corresponds to the given criteria.
487
488 @param session the session
489 @param charset is the charset to use (it can be NULL)
490 @param key is the list of criteria
491 @param result the search result is stored in (* result),
492 this structure have to be freed with mail_search_result_free()
493
494 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
495 on error
496*/
497
498#if 0
499int mailsession_search_messages(mailsession * session, char * charset,
500 struct mail_search_key * key,
501 struct mail_search_result ** result);
502#endif
503
504/*
505 mailsession_get_message returns a mailmessage structure that corresponds
506 to the given message number.
507 * WARNING * mailsession_get_message_by_uid() should be used instead.
508
509 @param session the session
510 @param num the message number
511 @param result the allocated mailmessage structure will be stored
512 in (* result), this structure have to be freed with mailmessage_free()
513
514 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
515 on error
516*/
517
518int mailsession_get_message(mailsession * session,
519 uint32_t num, mailmessage ** result);
520
521/*
522 mailsession_get_message_by_uid returns a mailmessage structure
523 that corresponds to the given message unique identifier.
524 This is currently implemented only for cached drivers.
525 * WARNING * That will deprecates the use of mailsession_get_message()
526
527 @param session the session
528 @param uid the message unique identifier
529 @param result the allocated mailmessage structure will be stored
530 in (* result), this structure have to be freed with mailmessage_free()
531
532 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
533 on error
534*/
535
536int mailsession_get_message_by_uid(mailsession * session,
537 const char * uid, mailmessage ** result);
538
539#ifdef __cplusplus
540}
541#endif
542
543#endif
diff --git a/kmicromail/libetpan/generic/maildriver_errors.h b/kmicromail/libetpan/generic/maildriver_errors.h
new file mode 100644
index 0000000..118b259
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver_errors.h
@@ -0,0 +1,99 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDRIVER_ERRORS_H
37
38#define MAILDRIVER_ERRORS_H
39
40enum {
41 MAIL_NO_ERROR = 0,
42 MAIL_NO_ERROR_AUTHENTICATED,
43 MAIL_NO_ERROR_NON_AUTHENTICATED,
44 MAIL_ERROR_NOT_IMPLEMENTED,
45 MAIL_ERROR_UNKNOWN,
46 MAIL_ERROR_CONNECT,
47 MAIL_ERROR_BAD_STATE,
48 MAIL_ERROR_FILE,
49 MAIL_ERROR_STREAM,
50 MAIL_ERROR_LOGIN,
51 MAIL_ERROR_CREATE, /* 10 */
52 MAIL_ERROR_DELETE,
53 MAIL_ERROR_LOGOUT,
54 MAIL_ERROR_NOOP,
55 MAIL_ERROR_RENAME,
56 MAIL_ERROR_CHECK,
57 MAIL_ERROR_EXAMINE,
58 MAIL_ERROR_SELECT,
59 MAIL_ERROR_MEMORY,
60 MAIL_ERROR_STATUS,
61 MAIL_ERROR_SUBSCRIBE, /* 20 */
62 MAIL_ERROR_UNSUBSCRIBE,
63 MAIL_ERROR_LIST,
64 MAIL_ERROR_LSUB,
65 MAIL_ERROR_APPEND,
66 MAIL_ERROR_COPY,
67 MAIL_ERROR_FETCH,
68 MAIL_ERROR_STORE,
69 MAIL_ERROR_SEARCH,
70 MAIL_ERROR_DISKSPACE,
71 MAIL_ERROR_MSG_NOT_FOUND, /* 30 */
72 MAIL_ERROR_PARSE,
73 MAIL_ERROR_INVAL,
74 MAIL_ERROR_PART_NOT_FOUND,
75 MAIL_ERROR_REMOVE,
76 MAIL_ERROR_FOLDER_NOT_FOUND,
77 MAIL_ERROR_MOVE,
78 MAIL_ERROR_STARTTLS,
79 MAIL_ERROR_CACHE_MISS,
80 MAIL_ERROR_NO_TLS,
81 MAIL_ERROR_EXPUNGE,
82 /* misc errors */
83 MAIL_ERROR_MISC,
84 MAIL_ERROR_PROTOCOL,
85 MAIL_ERROR_CAPABILITY,
86 MAIL_ERROR_CLOSE,
87 MAIL_ERROR_FATAL,
88 MAIL_ERROR_READONLY,
89 MAIL_ERROR_NO_APOP,
90 MAIL_ERROR_COMMAND_NOT_SUPPORTED,
91 MAIL_ERROR_NO_PERMISSION,
92 MAIL_ERROR_PROGRAM_ERROR,
93 MAIL_ERROR_SUBJECT_NOT_FOUND,
94 MAIL_ERROR_CHAR_ENCODING_FAILED,
95 MAIL_ERROR_SEND,
96 MAIL_ERROR_COMMAND,
97};
98
99#endif
diff --git a/kmicromail/libetpan/generic/maildriver_tools.c b/kmicromail/libetpan/generic/maildriver_tools.c
new file mode 100644
index 0000000..105fd9f
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver_tools.c
@@ -0,0 +1,841 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "maildriver_tools.h"
37
38#include "libetpan-config.h"
39
40#include <stdlib.h>
41#include <ctype.h>
42#include <string.h>
43#include <dirent.h>
44#include <unistd.h>
45
46#include "maildriver.h"
47#include "mailmessage.h"
48#include "mailstream.h"
49#include "mailmime.h"
50#include "mail_cache_db.h"
51
52/* ********************************************************************* */
53/* tools */
54
55
56int
57maildriver_generic_get_envelopes_list(mailsession * session,
58 struct mailmessage_list * env_list)
59{
60 int r;
61 unsigned i;
62#if 0
63 uint32_t j;
64 uint32_t last_msg;
65
66 last_msg = 0;
67#endif
68
69#if 0
70 j = 0;
71 i = 0;
72 while (i < env_list->tab->len) {
73 mailmessage * msg;
74 uint32_t index;
75
76 msg = carray_get(env_list->tab, i);
77
78 index = msg->index;
79
80 if (msg->fields == NULL) {
81 struct mailimf_fields * fields;
82
83 r = mailmessage_fetch_envelope(msg, &fields);
84 if (r != MAIL_NO_ERROR) {
85 /* do nothing */
86 }
87 else {
88 msg->fields = fields;
89
90 carray_set(env_list->tab, j, msg);
91
92 j ++;
93 last_msg = i + 1;
94 }
95 mailmessage_flush(msg);
96 }
97 else {
98 j ++;
99 last_msg = i + 1;
100 }
101
102 i ++;
103 }
104
105 for(i = last_msg ; i < env_list->tab->len ; i ++) {
106 mailmessage_free(carray_get(env_list->tab, i));
107 carray_set(env_list->tab, i, NULL);
108 }
109
110 r = carray_set_size(env_list->tab, j);
111 if (r < 0)
112 return MAIL_ERROR_MEMORY;
113#endif
114
115 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
116 mailmessage * msg;
117
118 msg = carray_get(env_list->msg_tab, i);
119
120 if (msg->msg_fields == NULL) {
121 struct mailimf_fields * fields;
122
123 r = mailmessage_fetch_envelope(msg, &fields);
124 if (r != MAIL_NO_ERROR) {
125 /* do nothing */
126 }
127 else {
128 msg->msg_fields = fields;
129 }
130 mailmessage_flush(msg);
131 }
132 }
133
134 return MAIL_NO_ERROR;
135}
136
137
138#if 0
139static int is_search_header_only(struct mail_search_key * key)
140{
141 clistiter * cur;
142 int result;
143
144 switch (key->type) {
145 case MAIL_SEARCH_KEY_ANSWERED:
146 case MAIL_SEARCH_KEY_BCC:
147 case MAIL_SEARCH_KEY_BEFORE:
148 case MAIL_SEARCH_KEY_CC:
149 case MAIL_SEARCH_KEY_DELETED:
150 case MAIL_SEARCH_KEY_FLAGGED:
151 case MAIL_SEARCH_KEY_FROM:
152 case MAIL_SEARCH_KEY_NEW:
153 case MAIL_SEARCH_KEY_OLD:
154 case MAIL_SEARCH_KEY_ON:
155 case MAIL_SEARCH_KEY_RECENT:
156 case MAIL_SEARCH_KEY_SEEN:
157 case MAIL_SEARCH_KEY_SINCE:
158 case MAIL_SEARCH_KEY_SUBJECT:
159 case MAIL_SEARCH_KEY_TO:
160 case MAIL_SEARCH_KEY_UNANSWERED:
161 case MAIL_SEARCH_KEY_UNDELETED:
162 case MAIL_SEARCH_KEY_UNFLAGGED:
163 case MAIL_SEARCH_KEY_UNSEEN:
164 case MAIL_SEARCH_KEY_HEADER:
165 case MAIL_SEARCH_KEY_LARGER:
166 case MAIL_SEARCH_KEY_NOT:
167 case MAIL_SEARCH_KEY_SMALLER:
168 case MAIL_SEARCH_KEY_ALL:
169 return TRUE;
170
171 case MAIL_SEARCH_KEY_BODY:
172 case MAIL_SEARCH_KEY_TEXT:
173 return FALSE;
174
175 case MAIL_SEARCH_KEY_OR:
176 return (is_search_header_only(key->or1) &&
177 is_search_header_only(key->or2));
178
179 case MAIL_SEARCH_KEY_MULTIPLE:
180 result = TRUE;
181 for (cur = clist_begin(key->multiple) ; cur != NULL ;
182 cur = clist_next(cur))
183 result = result && is_search_header_only(clist_content(cur));
184 return result;
185
186 default:
187 return TRUE;
188 }
189}
190
191static int match_header(struct mailimf_fields * fields,
192 char * name, char * value)
193{
194 clistiter * cur;
195
196 for(cur = clist_begin(fields->list) ; cur != NULL ;
197 cur = clist_content(cur)) {
198 struct mailimf_field * field;
199 struct mailimf_optional_field * opt_field;
200
201 field = clist_content(cur);
202 opt_field = field->optional_field;
203 if ((char) toupper((unsigned char) opt_field->name[0]) ==
204 (char) toupper((unsigned char) name[0])) {
205 if (strcasecmp(opt_field->name, name) == 0)
206 if (strstr(opt_field->value, value) != NULL)
207 return TRUE;
208 }
209 }
210 return FALSE;
211}
212
213static int comp_date(struct mailimf_fields * fields,
214 struct mailimf_date_time * ref_date)
215{
216 clistiter * cur;
217 struct mailimf_date_time * date;
218 int r;
219
220 date = NULL;
221 for(cur = clist_begin(fields->list) ; cur != NULL ;
222 cur = clist_content(cur)) {
223 struct mailimf_field * field;
224 struct mailimf_optional_field * opt_field;
225
226 field = clist_content(cur);
227 opt_field = field->optional_field;
228 if ((char) toupper((unsigned char) opt_field->name[0]) == 'D') {
229 if (strcasecmp(opt_field->name, "Date") == 0) {
230 size_t cur_token;
231
232 cur_token = 0;
233 r = mailimf_date_time_parse(opt_field->value, strlen(opt_field->value),
234 &cur_token, &date);
235 if (r == MAILIMF_NO_ERROR)
236 break;
237 else if (r == MAILIMF_ERROR_PARSE) {
238 /* do nothing */
239 }
240 else
241 break;
242 }
243 }
244 }
245
246 if (date == NULL)
247 return 0;
248
249 return mailimf_date_time_comp(date, ref_date);
250}
251
252static int match_messages(char * message,
253 size_t size,
254 struct mailimf_fields * fields,
255 int32_t flags,
256 char * charset,
257 struct mail_search_key * key)
258{
259 clistiter * cur;
260 size_t length;
261 size_t cur_token;
262 int r;
263
264 switch (key->type) {
265
266 /* flags */
267 case MAIL_SEARCH_KEY_ANSWERED:
268 return ((flags & MAIL_FLAG_ANSWERED) != 0);
269
270 case MAIL_SEARCH_KEY_FLAGGED:
271 return ((flags & MAIL_FLAG_FLAGGED) != 0);
272
273 case MAIL_SEARCH_KEY_DELETED:
274 return ((flags & MAIL_FLAG_DELETED) != 0);
275
276 case MAIL_SEARCH_KEY_RECENT:
277 return ((flags & MAIL_FLAG_NEW) != 0) &&
278 ((flags & MAIL_FLAG_SEEN) == 0);
279
280 case MAIL_SEARCH_KEY_SEEN:
281 return ((flags & MAIL_FLAG_SEEN) != 0);
282
283 case MAIL_SEARCH_KEY_NEW:
284 return ((flags & MAIL_FLAG_NEW) != 0);
285
286 case MAIL_SEARCH_KEY_OLD:
287 return ((flags & MAIL_FLAG_NEW) == 0);
288
289 case MAIL_SEARCH_KEY_UNANSWERED:
290 return ((flags & MAIL_FLAG_ANSWERED) == 0);
291
292 case MAIL_SEARCH_KEY_UNDELETED:
293 return ((flags & MAIL_FLAG_DELETED) == 0);
294
295 case MAIL_SEARCH_KEY_UNFLAGGED:
296 return ((flags & MAIL_FLAG_FLAGGED) == 0);
297
298 case MAIL_SEARCH_KEY_UNSEEN:
299 return ((flags & MAIL_FLAG_SEEN) == 0);
300
301 /* headers */
302 case MAIL_SEARCH_KEY_BCC:
303 return match_header(fields, "Bcc", key->bcc);
304
305 case MAIL_SEARCH_KEY_CC:
306 return match_header(fields, "Cc", key->cc);
307
308 case MAIL_SEARCH_KEY_FROM:
309 return match_header(fields, "From", key->from);
310
311 case MAIL_SEARCH_KEY_SUBJECT:
312 return match_header(fields, "Subject", key->subject);
313
314 case MAIL_SEARCH_KEY_TO:
315 return match_header(fields, "To", key->to);
316
317 case MAIL_SEARCH_KEY_HEADER:
318 return match_header(fields, key->header_name, key->header_value);
319
320 /* date */
321 case MAIL_SEARCH_KEY_BEFORE:
322 return (comp_date(fields, key->before) <= 0);
323
324 case MAIL_SEARCH_KEY_ON:
325 return (comp_date(fields, key->before) == 0);
326
327 case MAIL_SEARCH_KEY_SINCE:
328 return (comp_date(fields, key->before) >= 0);
329
330 /* boolean */
331 case MAIL_SEARCH_KEY_NOT:
332 return (!match_messages(message, size, fields, flags, charset, key->not));
333 case MAIL_SEARCH_KEY_OR:
334 return (match_messages(message, size, fields, flags, charset, key->or1) ||
335 match_messages(message, size, fields, flags, charset, key->or2));
336
337 case MAIL_SEARCH_KEY_MULTIPLE:
338 for(cur = clist_begin(key->multiple) ; cur != NULL ;
339 cur = clist_next(cur)) {
340 if (!match_messages(message, size, fields, flags, charset,
341 clist_content(cur)))
342 return FALSE;
343 }
344
345 return TRUE;
346
347 /* size */
348 case MAIL_SEARCH_KEY_SMALLER:
349 return (size <= key->smaller);
350
351 case MAIL_SEARCH_KEY_LARGER:
352 return (size >= key->larger);
353
354 case MAIL_SEARCH_KEY_BODY:
355 length = strlen(message);
356
357 cur_token = 0;
358 while (1) {
359 r = mailimf_ignore_field_parse(message, length, &cur_token);
360 if (r == MAILIMF_NO_ERROR) {
361 /* do nothing */
362 }
363 else
364 break;
365 }
366
367 return (strstr(message + cur_token, key->body) != NULL);
368
369 case MAIL_SEARCH_KEY_TEXT:
370 return (strstr(message, key->body) != NULL);
371
372 case MAIL_SEARCH_KEY_ALL:
373 default:
374 return TRUE;
375 }
376}
377
378int maildriver_generic_search_messages(mailsession * session, char * charset,
379 struct mail_search_key * key,
380 struct mail_search_result ** result)
381{
382 int header;
383 clist * list;
384 struct mail_search_result * search_result;
385 int r;
386 struct mailmessage_list * env_list;
387 int res;
388 unsigned int i;
389
390 header = is_search_header_only(key);
391
392 r = mailsession_get_messages_list(session, &env_list);
393 if (r != MAIL_NO_ERROR)
394 return r;
395
396 list = NULL;
397 for(i = 0 ; i < carray_count(env_list->tab) ; i ++) {
398 char * message;
399 size_t length;
400 struct mail_info * info;
401 uint32_t flags;
402 struct mailimf_fields * fields;
403 size_t cur_token;
404
405 info = carray_get(env_list->tab, i);
406
407 if (!header) {
408 r = mailsession_fetch_message(session, info->index, &message, &length);
409 if (r != MAIL_NO_ERROR) {
410 res = r;
411 goto free_list;
412 }
413
414 cur_token = 0;
415 r = mailimf_optional_fields_parse(message, length,
416 &cur_token, &fields);
417 if (r != MAILIMF_NO_ERROR) {
418 res = MAIL_ERROR_PARSE;
419 goto free_list;
420 }
421 }
422 else {
423 char * msg_header;
424 int r;
425 size_t cur_token;
426 size_t header_len;
427
428 r = mailsession_fetch_message_header(session, info->index, &msg_header,
429 &header_len);
430 if (r != MAIL_NO_ERROR) {
431 res = r;
432 goto free_list;
433 }
434
435 message = NULL;
436 cur_token = 0;
437 r = mailimf_optional_fields_parse(msg_header, header_len,
438 &cur_token, &fields);
439 if (r != MAILIMF_NO_ERROR) {
440 res = MAIL_ERROR_PARSE;
441 goto free_list;
442 }
443
444 mailsession_fetch_result_free(session, msg_header);
445 }
446
447 r = mailsession_get_message_flags(session, info->index, &flags);
448 if (r != MAIL_NO_ERROR) {
449 res = r;
450 goto free_list;
451 }
452
453 if (match_messages(message, info->size, fields, flags,
454 charset, key)) {
455 uint32_t * pnum;
456
457 pnum = malloc(sizeof(* pnum));
458 if (pnum == NULL) {
459 if (message != NULL)
460 mailsession_fetch_result_free(session, message);
461 res = MAIL_ERROR_MEMORY;
462 goto free_list;
463 }
464
465 * pnum = info->index;
466
467 r = clist_append(list, pnum);
468 if (r < 0) {
469 free(pnum);
470 if (message != NULL)
471 mailsession_fetch_result_free(session, message);
472 res = MAIL_ERROR_MEMORY;
473 goto free_list;
474 }
475 }
476
477 if (message != NULL)
478 mailsession_fetch_result_free(session, message);
479 }
480
481 search_result = mail_search_result_new(list);
482 if (search_result == NULL) {
483 res = MAIL_ERROR_MEMORY;
484 goto free_list;
485 }
486
487 * result = search_result;
488
489 return MAIL_NO_ERROR;
490
491 free_list:
492 clist_foreach(list, (clist_func) free, NULL);
493 clist_free(list);
494 mailmessage_list_free(env_list);
495 return res;
496}
497#endif
498
499#if 0
500int maildriver_generic_search_messages(mailsession * session, char * charset,
501 struct mail_search_key * key,
502 struct mail_search_result ** result)
503{
504 return MAIL_ERROR_NOT_IMPLEMENTED;
505}
506#endif
507
508int
509maildriver_env_list_to_msg_list(struct mailmessage_list * env_list,
510 clist ** result)
511{
512 clist * msg_list;
513 int r;
514 int res;
515 unsigned int i;
516
517 msg_list = clist_new();
518 if (msg_list == NULL) {
519 res = MAIL_ERROR_MEMORY;
520 goto err;
521 }
522
523 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
524 mailmessage * msg;
525
526 msg = carray_get(env_list->msg_tab, i);
527
528 if (msg->msg_fields == NULL) {
529 uint32_t * pindex;
530
531 pindex = malloc(sizeof(* pindex));
532 if (pindex == NULL) {
533 res = MAIL_ERROR_MEMORY;
534 goto free_msg_list;
535 }
536
537 * pindex = msg->msg_index;
538
539 r = clist_append(msg_list, pindex);
540 if (r < 0) {
541 free(pindex);
542 res = MAIL_ERROR_MEMORY;
543 goto free_msg_list;
544 }
545
546 }
547 }
548
549 * result = msg_list;
550
551 return MAIL_NO_ERROR;
552
553 free_msg_list:
554 clist_foreach(msg_list, (clist_func) free, NULL);
555 clist_free(msg_list);
556 err:
557 return res;
558}
559
560
561int
562maildriver_env_list_to_msg_list_no_flags(struct mailmessage_list * env_list,
563 clist ** result)
564{
565 clist * msg_list;
566 int r;
567 int res;
568 unsigned int i;
569
570 msg_list = clist_new();
571 if (msg_list == NULL) {
572 res = MAIL_ERROR_MEMORY;
573 goto err;
574 }
575
576 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
577 mailmessage * msg;
578
579 msg = carray_get(env_list->msg_tab, i);
580
581 if (msg->msg_flags == NULL) {
582 uint32_t * pindex;
583
584 pindex = malloc(sizeof(* pindex));
585 if (pindex == NULL) {
586 res = MAIL_ERROR_MEMORY;
587 goto free_msg_list;
588 }
589
590 * pindex = msg->msg_index;
591
592 r = clist_append(msg_list, pindex);
593 if (r < 0) {
594 free(pindex);
595 res = MAIL_ERROR_MEMORY;
596 goto free_msg_list;
597 }
598
599 }
600 }
601
602 * result = msg_list;
603
604 return MAIL_NO_ERROR;
605
606 free_msg_list:
607 clist_foreach(msg_list, (clist_func) free, NULL);
608 clist_free(msg_list);
609 err:
610 return res;
611}
612
613
614
615int maildriver_imf_error_to_mail_error(int error)
616{
617 switch (error) {
618 case MAILIMF_NO_ERROR:
619 return MAIL_NO_ERROR;
620
621 case MAILIMF_ERROR_PARSE:
622 return MAIL_ERROR_PARSE;
623
624 case MAILIMF_ERROR_MEMORY:
625 return MAIL_ERROR_MEMORY;
626
627 case MAILIMF_ERROR_INVAL:
628 return MAIL_ERROR_INVAL;
629
630 case MAILIMF_ERROR_FILE:
631 return MAIL_ERROR_FILE;
632
633 default:
634 return MAIL_ERROR_INVAL;
635 }
636}
637
638char * maildriver_quote_mailbox(char * mb)
639{
640 MMAPString * gstr;
641 char * str;
642
643 gstr = mmap_string_new("");
644 if (gstr == NULL)
645 return NULL;
646
647 while (* mb != 0) {
648 char hex[3];
649
650 if (((* mb >= 'a') && (* mb <= 'z')) ||
651 ((* mb >= 'A') && (* mb <= 'Z')) ||
652 ((* mb >= '0') && (* mb <= '9')))
653 mmap_string_append_c(gstr, * mb);
654 else {
655 if (mmap_string_append_c(gstr, '%') == NULL)
656 goto free;
657 snprintf(hex, 3, "%02x", (unsigned char) (* mb));
658 if (mmap_string_append(gstr, hex) == NULL)
659 goto free;
660 }
661 mb ++;
662 }
663
664 str = strdup(gstr->str);
665 if (str == NULL)
666 goto free;
667
668 mmap_string_free(gstr);
669
670 return str;
671
672 free:
673 mmap_string_free(gstr);
674 return NULL;
675}
676
677
678
679int maildriver_cache_clean_up(struct mail_cache_db * cache_db_env,
680 struct mail_cache_db * cache_db_flags,
681 struct mailmessage_list * env_list)
682{
683 chash * hash_exist;
684 int res;
685 int r;
686 char keyname[PATH_MAX];
687 unsigned int i;
688
689 /* flush cache */
690
691 hash_exist = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYALL);
692 if (hash_exist == NULL) {
693 res = MAIL_ERROR_MEMORY;
694 goto err;
695 }
696
697 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
698 mailmessage * msg;
699 chashdatum key;
700 chashdatum value;
701
702 msg = carray_get(env_list->msg_tab, i);
703
704 value.data = NULL;
705 value.len = 0;
706
707 if (cache_db_env != NULL) {
708 snprintf(keyname, PATH_MAX, "%s-envelope", msg->msg_uid);
709
710 key.data = keyname;
711 key.len = strlen(keyname);
712 r = chash_set(hash_exist, &key, &value, NULL);
713 if (r < 0) {
714 res = MAIL_ERROR_MEMORY;
715 goto free;
716 }
717 }
718
719 if (cache_db_flags != NULL) {
720 snprintf(keyname, PATH_MAX, "%s-flags", msg->msg_uid);
721
722 key.data = keyname;
723 key.len = strlen(keyname);
724 r = chash_set(hash_exist, &key, &value, NULL);
725 if (r < 0) {
726 res = MAIL_ERROR_MEMORY;
727 goto free;
728 }
729 }
730 }
731
732 /* clean up */
733 if (cache_db_env != NULL)
734 mail_cache_db_clean_up(cache_db_env, hash_exist);
735 if (cache_db_flags != NULL)
736 mail_cache_db_clean_up(cache_db_flags, hash_exist);
737
738 chash_free(hash_exist);
739
740 return MAIL_NO_ERROR;
741
742 free:
743 chash_free(hash_exist);
744 err:
745 return res;
746}
747
748
749/*
750 maildriver_message_cache_clean_up()
751
752 remove files in cache_dir that does not correspond to a message.
753
754 get_uid_from_filename() modifies the given filename so that it
755 is a uid when returning from the function. If get_uid_from_filename()
756 clears the content of file (set to empty string), this means that
757 this file should not be deleted.
758*/
759
760int maildriver_message_cache_clean_up(char * cache_dir,
761 struct mailmessage_list * env_list,
762 void (* get_uid_from_filename)(char *))
763{
764 chash * hash_exist;
765 DIR * d;
766 char cached_filename[PATH_MAX];
767 struct dirent * ent;
768 char keyname[PATH_MAX];
769 unsigned int i;
770 int res;
771 int r;
772
773 /* remove files */
774
775 hash_exist = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYALL);
776 if (hash_exist == NULL) {
777 res = MAIL_ERROR_MEMORY;
778 goto err;
779 }
780
781 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
782 mailmessage * msg;
783 chashdatum key;
784 chashdatum value;
785
786 msg = carray_get(env_list->msg_tab, i);
787
788 key.data = msg->msg_uid;
789 key.len = strlen(msg->msg_uid);
790 value.data = NULL;
791 value.len = 0;
792 r = chash_set(hash_exist, &key, &value, NULL);
793 if (r < 0) {
794 res = MAIL_ERROR_MEMORY;
795 goto free;
796 }
797 }
798
799 d = opendir(cache_dir);
800 while ((ent = readdir(d)) != NULL) {
801 chashdatum key;
802 chashdatum value;
803
804 if (strcmp(ent->d_name, ".") == 0)
805 continue;
806
807 if (strcmp(ent->d_name, "..") == 0)
808 continue;
809
810 if (strstr(ent->d_name, ".db") != NULL)
811 continue;
812
813 strncpy(keyname, ent->d_name, sizeof(keyname));
814 keyname[sizeof(keyname) - 1] = '\0';
815
816 get_uid_from_filename(keyname);
817
818 if (* keyname == '\0')
819 continue;
820
821 key.data = keyname;
822 key.len = strlen(keyname);
823
824 r = chash_get(hash_exist, &key, &value);
825 if (r < 0) {
826 snprintf(cached_filename, sizeof(cached_filename),
827 "%s/%s", cache_dir, ent->d_name);
828 unlink(cached_filename);
829 }
830 }
831 closedir(d);
832
833 chash_free(hash_exist);
834
835 return MAIL_NO_ERROR;
836
837 free:
838 chash_free(hash_exist);
839 err:
840 return res;
841}
diff --git a/kmicromail/libetpan/generic/maildriver_tools.h b/kmicromail/libetpan/generic/maildriver_tools.h
new file mode 100644
index 0000000..eaddc5d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver_tools.h
@@ -0,0 +1,81 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDRIVER_TOOLS_H
37
38#define MAILDRIVER_TOOLS_H
39
40#include "maildriver_types.h"
41#include "mail_cache_db_types.h"
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47int
48maildriver_generic_get_envelopes_list(mailsession * session,
49 struct mailmessage_list * env_list);
50
51#if 0
52int maildriver_generic_search_messages(mailsession * session, char * charset,
53 struct mail_search_key * key,
54 struct mail_search_result ** result);
55#endif
56
57int
58maildriver_env_list_to_msg_list(struct mailmessage_list * env_list,
59 clist ** result);
60
61int maildriver_imf_error_to_mail_error(int error);
62
63char * maildriver_quote_mailbox(char * mb);
64
65int
66maildriver_env_list_to_msg_list_no_flags(struct mailmessage_list * env_list,
67 clist ** result);
68
69int maildriver_cache_clean_up(struct mail_cache_db * cache_db_env,
70 struct mail_cache_db * cache_db_flags,
71 struct mailmessage_list * env_list);
72
73int maildriver_message_cache_clean_up(char * cache_dir,
74 struct mailmessage_list * env_list,
75 void (* get_uid_from_filename)(char *));
76
77#ifdef __cplusplus
78}
79#endif
80
81#endif
diff --git a/kmicromail/libetpan/generic/maildriver_types.c b/kmicromail/libetpan/generic/maildriver_types.c
new file mode 100644
index 0000000..7b3b348
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver_types.c
@@ -0,0 +1,340 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "maildriver_types.h"
37#include <time.h>
38#include <stdlib.h>
39#include "mailmessage.h"
40
41struct mailmessage_list * mailmessage_list_new(carray * msg_tab)
42{
43 struct mailmessage_list * env_list;
44
45 env_list = malloc(sizeof(* env_list));
46 if (env_list == NULL)
47 return NULL;
48
49 env_list->msg_tab = msg_tab;
50
51 return env_list;
52}
53
54void mailmessage_list_free(struct mailmessage_list * env_list)
55{
56 unsigned int i;
57
58 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
59 mailmessage * msg;
60
61 msg = carray_get(env_list->msg_tab, i);
62 if (msg != NULL)
63 mailmessage_free(msg);
64 }
65 carray_free(env_list->msg_tab);
66 free(env_list);
67}
68
69struct mail_list * mail_list_new(clist * list)
70{
71 struct mail_list * resp;
72
73 resp = malloc(sizeof(* resp));
74 if (resp == NULL)
75 return NULL;
76 resp->mb_list = list;
77
78 return resp;
79}
80
81void mail_list_free(struct mail_list * resp)
82{
83 clist_foreach(resp->mb_list, (clist_func) free, NULL);
84 clist_free(resp->mb_list);
85 free(resp);
86}
87
88static int32_t mailimf_date_time_to_int(struct mailimf_date_time * date)
89{
90 return date->dt_year * 12 * 30 * 24 * 60 * 60 +
91 date->dt_month * 30 * 24 * 60 * 60 + date->dt_day * 24 * 60 * 60 +
92 (date->dt_hour - date->dt_zone) * 60 * 60 +
93 date->dt_min * 60 + date->dt_sec;
94}
95
96int32_t mailimf_date_time_comp(struct mailimf_date_time * date1,
97 struct mailimf_date_time * date2)
98{
99 return mailimf_date_time_to_int(date1) - mailimf_date_time_to_int(date2);
100}
101
102
103
104
105
106
107
108#if 0
109struct mail_search_key *
110mail_search_key_new(int sk_type,
111 char * sk_bcc,
112 struct mailimf_date_time * sk_before,
113 char * sk_body,
114 char * sk_cc,
115 char * sk_from,
116 struct mailimf_date_time * sk_on,
117 struct mailimf_date_time * sk_since,
118 char * sk_subject,
119 char * sk_text,
120 char * sk_to,
121 char * sk_header_name,
122 char * sk_header_value,
123 size_t sk_larger,
124 struct mail_search_key * sk_not,
125 struct mail_search_key * sk_or1,
126 struct mail_search_key * sk_or2,
127 size_t sk_smaller,
128 clist * sk_multiple)
129{
130 struct mail_search_key * key;
131
132 key = malloc(sizeof(* key));
133 if (key == NULL)
134 return NULL;
135
136 key->sk_type = sk_type;
137 key->sk_bcc = sk_bcc;
138 key->sk_before = sk_before;
139 key->sk_body = sk_body;
140 key->sk_cc = sk_cc;
141 key->sk_from = sk_from;
142 key->sk_on = sk_on;
143 key->sk_since = sk_since;
144 key->sk_subject = sk_subject;
145 key->sk_text = sk_text;
146 key->sk_to = sk_to;
147 key->sk_header_name = sk_header_name;
148 key->sk_header_value = sk_header_value;
149 key->sk_larger = sk_larger;
150 key->sk_not = sk_not;
151 key->sk_or1 = sk_or1;
152 key->sk_or2 = sk_or2;
153 key->sk_smaller = sk_smaller;
154 key->sk_multiple = sk_multiple;
155
156 return key;
157}
158
159
160void mail_search_key_free(struct mail_search_key * key)
161{
162 if (key->sk_bcc)
163 free(key->sk_bcc);
164 if (key->sk_before)
165 mailimf_date_time_free(key->sk_before);
166 if (key->sk_body)
167 free(key->sk_body);
168 if (key->sk_cc)
169 free(key->sk_cc);
170 if (key->sk_from)
171 free(key->sk_from);
172 if (key->sk_on)
173 mailimf_date_time_free(key->sk_on);
174 if (key->sk_since)
175 mailimf_date_time_free(key->sk_since);
176 if (key->sk_subject)
177 free(key->sk_subject);
178 if (key->sk_text)
179 free(key->sk_text);
180 if (key->sk_to)
181 free(key->sk_to);
182 if (key->sk_header_name)
183 free(key->sk_header_name);
184 if (key->sk_header_value)
185 free(key->sk_header_value);
186 if (key->sk_not)
187 mail_search_key_free(key->sk_not);
188 if (key->sk_or1)
189 mail_search_key_free(key->sk_or1);
190 if (key->sk_or2)
191 mail_search_key_free(key->sk_or2);
192 if (key->sk_multiple) {
193 clist_foreach(key->sk_multiple, (clist_func) mail_search_key_free, NULL);
194 clist_free(key->sk_multiple);
195 }
196
197 free(key);
198}
199
200
201struct mail_search_result * mail_search_result_new(clist * list)
202{
203 struct mail_search_result * search_result;
204
205 search_result = malloc(sizeof(* search_result));
206 if (search_result == NULL)
207 return NULL;
208 search_result->list = list;
209
210 return search_result;
211}
212
213void mail_search_result_free(struct mail_search_result * search_result)
214{
215 clist_foreach(search_result->list, (clist_func) free, NULL);
216 clist_free(search_result->list);
217 free(search_result);
218}
219#endif
220
221struct error_message {
222 int code;
223 char * message;
224};
225
226static struct error_message message_tab[] = {
227{ MAIL_NO_ERROR, "no error" },
228{ MAIL_NO_ERROR_AUTHENTICATED, "no error - authenticated" },
229{ MAIL_NO_ERROR_NON_AUTHENTICATED, "no error - not authenticated" },
230{ MAIL_ERROR_NOT_IMPLEMENTED, "not implemented" },
231{ MAIL_ERROR_UNKNOWN, "unknown"},
232{ MAIL_ERROR_CONNECT, "connect"},
233{ MAIL_ERROR_BAD_STATE, "bad state"},
234{ MAIL_ERROR_FILE, "file error - file could not be accessed" },
235{ MAIL_ERROR_STREAM, "stream error - socket could not be read or written" },
236{ MAIL_ERROR_LOGIN, "login error" },
237{ MAIL_ERROR_CREATE, "create error" },
238{ MAIL_ERROR_DELETE, /* 10 */ "delete error" },
239{ MAIL_ERROR_LOGOUT, "logout error" },
240{ MAIL_ERROR_NOOP, "noop error" },
241{ MAIL_ERROR_RENAME, "rename error" },
242{ MAIL_ERROR_CHECK, "check error" },
243{ MAIL_ERROR_EXAMINE, "examine error" },
244{ MAIL_ERROR_SELECT, "select error - folder does not exist" },
245{ MAIL_ERROR_MEMORY, "not enough memory" },
246{ MAIL_ERROR_STATUS, "status error" },
247{ MAIL_ERROR_SUBSCRIBE, "subscribe error" },
248{ MAIL_ERROR_UNSUBSCRIBE, /* 20 */ "unsubscribe error" },
249{ MAIL_ERROR_LIST, "list error" },
250{ MAIL_ERROR_LSUB, "lsub error" },
251{ MAIL_ERROR_APPEND, "append error - mail could not be appended" },
252{ MAIL_ERROR_COPY, "copy error" },
253{ MAIL_ERROR_FETCH, "fetch error" },
254{ MAIL_ERROR_STORE, "store error" },
255{ MAIL_ERROR_SEARCH, "search error" },
256{ MAIL_ERROR_DISKSPACE, " error: not enough diskspace" },
257{ MAIL_ERROR_MSG_NOT_FOUND, "message not found" },
258{ MAIL_ERROR_PARSE, /* 30 */ "parse error" },
259{ MAIL_ERROR_INVAL, "invalid parameter for the function" },
260{ MAIL_ERROR_PART_NOT_FOUND, "mime part of the message is not found" },
261{ MAIL_ERROR_REMOVE, "remove error - the message did not exist" },
262{ MAIL_ERROR_FOLDER_NOT_FOUND, "folder not found" },
263{ MAIL_ERROR_MOVE, "move error" },
264{ MAIL_ERROR_STARTTLS, "starttls error" },
265{ MAIL_ERROR_CACHE_MISS, "mail cache missed" },
266{ MAIL_ERROR_NO_TLS, "no starttls" },
267{ MAIL_ERROR_EXPUNGE, "expunge error" },
268{ MAIL_ERROR_PROTOCOL, "protocol error - server did not respect the protocol" },
269{ MAIL_ERROR_CAPABILITY, "capability error" },
270{ MAIL_ERROR_CLOSE, "close error" },
271{ MAIL_ERROR_FATAL, "fatal error" },
272{ MAIL_ERROR_READONLY, "mailbox is readonly" },
273{ MAIL_ERROR_NO_APOP, "pop3 error - no apop" },
274{ MAIL_ERROR_COMMAND_NOT_SUPPORTED, "nntp error - command not supported" },
275{ MAIL_ERROR_NO_PERMISSION, "nntp error - no permission" },
276{ MAIL_ERROR_PROGRAM_ERROR, "nntp error - program error" },
277{ MAIL_ERROR_SUBJECT_NOT_FOUND, "internal threading error - subject not found" }};
278
279const char * maildriver_strerror(int err)
280{
281 int count;
282 int i;
283
284 count = sizeof(message_tab) / sizeof(struct error_message);
285
286 for(i = 0 ; i < count ; i++) {
287 if (message_tab[i].code == err) {
288 return message_tab[i].message;
289 }
290 }
291
292 return "unknown error";
293}
294
295
296struct mail_flags * mail_flags_new_empty(void)
297{
298 struct mail_flags * flags;
299
300 flags = malloc(sizeof(* flags));
301 if (flags == NULL)
302 goto err;
303
304 flags->fl_flags = MAIL_FLAG_NEW;
305 flags->fl_extension = clist_new();
306 if (flags->fl_extension == NULL)
307 goto free;
308
309 return flags;
310
311 free:
312 free(flags);
313 err:
314 return NULL;
315}
316
317struct mail_flags * mail_flags_new(uint32_t fl_flags, clist * fl_extension)
318{
319 struct mail_flags * flags;
320
321 flags = malloc(sizeof(* flags));
322 if (flags == NULL)
323 goto err;
324
325 flags->fl_flags = fl_flags;
326 flags->fl_extension = fl_extension;
327
328 return flags;
329
330err:
331 return NULL;
332}
333
334void mail_flags_free(struct mail_flags * flags)
335{
336 clist_foreach(flags->fl_extension, (clist_func) free, NULL);
337 clist_free(flags->fl_extension);
338 free(flags);
339}
340
diff --git a/kmicromail/libetpan/generic/maildriver_types.h b/kmicromail/libetpan/generic/maildriver_types.h
new file mode 100644
index 0000000..3ff9440
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver_types.h
@@ -0,0 +1,793 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDRIVER_TYPES_H
37
38#define MAILDRIVER_TYPES_H
39
40#include <inttypes.h>
41#include <sys/types.h>
42
43#include <libetpan/mailstream.h>
44#include <libetpan/mailimf.h>
45#include <libetpan/mailmime.h>
46#include <libetpan/carray.h>
47
48#include <libetpan/mailthread_types.h>
49#include <libetpan/maildriver_errors.h>
50
51#ifdef __cplusplus
52extern "C" {
53#endif
54
55typedef struct mailsession_driver mailsession_driver;
56
57typedef struct mailsession mailsession;
58
59typedef struct mailmessage_driver mailmessage_driver;
60
61typedef struct mailmessage mailmessage;
62
63
64/*
65 mailmessage_list is a list of mailmessage
66
67 - tab is an array of mailmessage structures
68*/
69
70struct mailmessage_list {
71 carray * msg_tab; /* elements are (mailmessage *) */
72};
73
74struct mailmessage_list * mailmessage_list_new(carray * msg_tab);
75void mailmessage_list_free(struct mailmessage_list * env_list);
76
77/*
78 mail_list is a list of mailbox names
79
80 - list is a list of mailbox names
81*/
82
83struct mail_list {
84 clist * mb_list; /* elements are (char *) */
85};
86
87struct mail_list * mail_list_new(clist * mb_list);
88void mail_list_free(struct mail_list * resp);
89
90/*
91 This is a flag value.
92 Flags can be combined with OR operation
93*/
94
95enum {
96 MAIL_FLAG_NEW = 1 << 0,
97 MAIL_FLAG_SEEN = 1 << 1,
98 MAIL_FLAG_FLAGGED = 1 << 2,
99 MAIL_FLAG_DELETED = 1 << 3,
100 MAIL_FLAG_ANSWERED = 1 << 4,
101 MAIL_FLAG_FORWARDED = 1 << 5,
102 MAIL_FLAG_CANCELLED = 1 << 6,
103};
104
105/*
106 mail_flags is the value of a flag related to a message.
107
108 - flags is the standard flags value
109
110 - extension is a list of unknown flags for libEtPan!
111*/
112
113struct mail_flags {
114 uint32_t fl_flags;
115 clist * fl_extension; /* elements are (char *) */
116};
117
118struct mail_flags * mail_flags_new(uint32_t fl_flags, clist * fl_ext);
119void mail_flags_free(struct mail_flags * flags);
120
121/*
122 This function creates a flag for a new message
123*/
124
125struct mail_flags * mail_flags_new_empty(void);
126
127
128/*
129 mailimf_date_time_comp compares two dates
130
131
132*/
133
134int32_t mailimf_date_time_comp(struct mailimf_date_time * date1,
135 struct mailimf_date_time * date2);
136
137/*
138 this is type type of the search criteria
139*/
140
141enum {
142 MAIL_SEARCH_KEY_ALL, /* all messages correspond */
143 MAIL_SEARCH_KEY_ANSWERED, /* messages with flag \Answered */
144 MAIL_SEARCH_KEY_BCC, /* messages which Bcc field contains
145 a given string */
146 MAIL_SEARCH_KEY_BEFORE, /* messages which internal date is earlier
147 than the specified date */
148 MAIL_SEARCH_KEY_BODY, /* message that contains the given string
149 (in header and text parts) */
150 MAIL_SEARCH_KEY_CC, /* messages whose Cc field contains the
151 given string */
152 MAIL_SEARCH_KEY_DELETED, /* messages with the flag \Deleted */
153 MAIL_SEARCH_KEY_FLAGGED, /* messages with the flag \Flagged */
154 MAIL_SEARCH_KEY_FROM, /* messages whose From field contains the
155 given string */
156 MAIL_SEARCH_KEY_NEW, /* messages with the flag \Recent and not
157 the \Seen flag */
158 MAIL_SEARCH_KEY_OLD, /* messages that do not have the
159 \Recent flag set */
160 MAIL_SEARCH_KEY_ON, /* messages whose internal date is the
161 specified date */
162 MAIL_SEARCH_KEY_RECENT, /* messages with the flag \Recent */
163 MAIL_SEARCH_KEY_SEEN, /* messages with the flag \Seen */
164 MAIL_SEARCH_KEY_SINCE, /* messages whose internal date is later
165 than specified date */
166 MAIL_SEARCH_KEY_SUBJECT, /* messages whose Subject field contains the
167 given string */
168 MAIL_SEARCH_KEY_TEXT, /* messages whose text part contains the
169 given string */
170 MAIL_SEARCH_KEY_TO, /* messages whose To field contains the
171 given string */
172 MAIL_SEARCH_KEY_UNANSWERED, /* messages with no flag \Answered */
173 MAIL_SEARCH_KEY_UNDELETED, /* messages with no flag \Deleted */
174 MAIL_SEARCH_KEY_UNFLAGGED, /* messages with no flag \Flagged */
175 MAIL_SEARCH_KEY_UNSEEN, /* messages with no flag \Seen */
176 MAIL_SEARCH_KEY_HEADER, /* messages whose given field
177 contains the given string */
178 MAIL_SEARCH_KEY_LARGER, /* messages whose size is larger then
179 the given size */
180 MAIL_SEARCH_KEY_NOT, /* not operation of the condition */
181 MAIL_SEARCH_KEY_OR, /* or operation between two conditions */
182 MAIL_SEARCH_KEY_SMALLER, /* messages whose size is smaller than
183 the given size */
184 MAIL_SEARCH_KEY_MULTIPLE /* the boolean operator between the
185 conditions is AND */
186};
187
188/*
189 mail_search_key is the condition on the messages to return
190
191 - type is the type of the condition
192
193 - bcc is the text to search in the Bcc field when type is
194 MAIL_SEARCH_KEY_BCC, should be allocated with malloc()
195
196 - before is a date when type is MAIL_SEARCH_KEY_BEFORE
197
198 - body is the text to search in the message when type is
199 MAIL_SEARCH_KEY_BODY, should be allocated with malloc()
200
201 - cc is the text to search in the Cc field when type is
202 MAIL_SEARCH_KEY_CC, should be allocated with malloc()
203
204 - from is the text to search in the From field when type is
205 MAIL_SEARCH_KEY_FROM, should be allocated with malloc()
206
207 - on is a date when type is MAIL_SEARCH_KEY_ON
208
209 - since is a date when type is MAIL_SEARCH_KEY_SINCE
210
211 - subject is the text to search in the Subject field when type is
212 MAILIMAP_SEARCH_KEY_SUBJECT, should be allocated with malloc()
213
214 - text is the text to search in the text part of the message when
215 type is MAILIMAP_SEARCH_KEY_TEXT, should be allocated with malloc()
216
217 - to is the text to search in the To field when type is
218 MAILIMAP_SEARCH_KEY_TO, should be allocated with malloc()
219
220 - header_name is the header name when type is MAILIMAP_SEARCH_KEY_HEADER,
221 should be allocated with malloc()
222
223 - header_value is the text to search in the given header when type is
224 MAILIMAP_SEARCH_KEY_HEADER, should be allocated with malloc()
225
226 - larger is a size when type is MAILIMAP_SEARCH_KEY_LARGER
227
228 - not is a condition when type is MAILIMAP_SEARCH_KEY_NOT
229
230 - or1 is a condition when type is MAILIMAP_SEARCH_KEY_OR
231
232 - or2 is a condition when type is MAILIMAP_SEARCH_KEY_OR
233
234 - sentbefore is a date when type is MAILIMAP_SEARCH_KEY_SENTBEFORE
235
236 - senton is a date when type is MAILIMAP_SEARCH_KEY_SENTON
237
238 - sentsince is a date when type is MAILIMAP_SEARCH_KEY_SENTSINCE
239
240 - smaller is a size when type is MAILIMAP_SEARCH_KEY_SMALLER
241
242 - multiple is a set of message when type is MAILIMAP_SEARCH_KEY_MULTIPLE
243*/
244
245#if 0
246struct mail_search_key {
247 int sk_type;
248 union {
249 char * sk_bcc;
250 struct mailimf_date_time * sk_before;
251 char * sk_body;
252 char * sk_cc;
253 char * sk_from;
254 struct mailimf_date_time * sk_on;
255 struct mailimf_date_time * sk_since;
256 char * sk_subject;
257 char * sk_text;
258 char * sk_to;
259 char * sk_header_name;
260 char * sk_header_value;
261 size_t sk_larger;
262 struct mail_search_key * sk_not;
263 struct mail_search_key * sk_or1;
264 struct mail_search_key * sk_or2;
265 size_t sk_smaller;
266 clist * sk_multiple; /* list of (struct mailimap_search_key *) */
267 } sk_data;
268};
269
270
271struct mail_search_key *
272mail_search_key_new(int sk_type,
273 char * sk_bcc, struct mailimf_date_time * sk_before,
274 char * sk_body, char * sk_cc, char * sk_from,
275 struct mailimf_date_time * sk_on, struct mailimf_date_time * sk_since,
276 char * sk_subject, char * sk_text, char * sk_to,
277 char * sk_header_name, char * sk_header_value, size_t sk_larger,
278 struct mail_search_key * sk_not, struct mail_search_key * sk_or1,
279 struct mail_search_key * sk_or2, size_t sk_smaller,
280 clist * sk_multiple);
281
282void mail_search_key_free(struct mail_search_key * key);
283#endif
284
285/*
286 mail_search_result is a list of message numbers that is returned
287 by the mailsession_search_messages function()
288*/
289
290#if 0
291struct mail_search_result {
292 clist * sr_list; /* list of (uint32_t *) */
293};
294
295struct mail_search_result * mail_search_result_new(clist * sr_list);
296
297void mail_search_result_free(struct mail_search_result * search_result);
298#endif
299
300
301/*
302 There is three kinds of identities :
303 - storage
304 - folders
305 - session
306
307 A storage (struct mailstorage) represents whether a server or
308 a main path,
309
310 A storage can be an IMAP server, the root path of a MH or a mbox file.
311
312 Folders (struct mailfolder) are the mailboxes we can
313 choose in the server or as sub-folder of the main path.
314
315 Folders for IMAP are the IMAP mailboxes, for MH this is one of the
316 folder of the MH storage, for mbox, there is only one folder, the
317 mbox file content;
318
319 A mail session (struct mailsession) is whether a connection to a server
320 or a path that is open. It is the abstraction lower folders and storage.
321 It allow us to send commands.
322
323 We have a session driver for mail session for each kind of storage.
324
325 From a session, we can get a message (struct mailmessage) to read.
326 We have a message driver for each kind of storage.
327*/
328
329/*
330 maildriver is the driver structure for mail sessions
331
332 - name is the name of the driver
333
334 - initialize() is the function that will initializes a data structure
335 specific to the driver, it returns a value that will be stored
336 in the field data of the session.
337 The field data of the session is the state of the session,
338 the internal data structure used by the driver.
339 It is called when creating the mailsession structure with
340 mailsession_new().
341
342 - uninitialize() frees the structure created with initialize()
343
344 - parameters() implements functions specific to the given mail access
345
346 - connect_stream() connects a stream to the session
347
348 - connect_path() notify a main path to the session
349
350 - starttls() changes the current stream to a TLS stream
351
352 - login() notifies the user and the password to authenticate to the
353 session
354
355 - logout() exits the session and closes the stream
356
357 - noop() does no operation on the session, but it can be
358 used to poll for the status of the connection.
359
360 - build_folder_name() will return an allocated string with
361 that contains the complete path of the folder to create
362
363 - create_folder() creates the folder that corresponds to the
364 given name
365
366 - delete_folder() deletes the folder that corresponds to the
367 given name
368
369 - rename_folder() change the name of the folder
370
371 - check_folder() makes a checkpoint of the session
372
373 - examine_folder() selects a mailbox as readonly
374
375 - select_folder() selects a mailbox
376
377 - expunge_folder() deletes all messages marked \Deleted
378
379 - status_folder() queries the status of the folder
380 (number of messages, number of recent messages, number of
381 unseen messages)
382
383 - messages_number() queries the number of messages in the folder
384
385 - recent_number() queries the number of recent messages in the folder
386
387 - unseen_number() queries the number of unseen messages in the folder
388
389 - list_folders() returns the list of all sub-mailboxes
390 of the given mailbox
391
392 - lsub_folders() returns the list of subscribed
393 sub-mailboxes of the given mailbox
394
395 - subscribe_folder() subscribes to the given mailbox
396
397 - unsubscribe_folder() unsubscribes to the given mailbox
398
399 - append_message() adds a RFC 2822 message to the current
400 given mailbox
401
402 - copy_message() copies a message whose number is given to
403 a given mailbox. The mailbox must be accessible from
404 the same session.
405
406 - move_message() copies a message whose number is given to
407 a given mailbox. The mailbox must be accessible from the
408 same session.
409
410 - get_messages_list() returns the list of message numbers
411 of the current mailbox.
412
413 - get_envelopes_list() fills the parsed fields in the
414 mailmessage structures of the mailmessage_list.
415
416 - remove_message() removes the given message from the mailbox.
417 The message is permanently deleted.
418
419 - search_message() returns a list of message numbers that
420 corresponds to the given criteria.
421
422 - get_message returns a mailmessage structure that corresponds
423 to the given message number.
424
425 - get_message_by_uid returns a mailmessage structure that corresponds
426 to the given message unique identifier.
427
428 * mandatory functions are the following :
429
430 - connect_stream() of connect_path()
431 - logout()
432 - get_messages_list()
433 - get_envelopes_list()
434
435 * we advise you to implement these functions :
436
437 - select_folder() (in case a session can access several folders)
438 - noop() (to check if the server is responding)
439 - check_folder() (to make a checkpoint of the session)
440 - status_folder(), messages_number(), recent_number(), unseen_number()
441 (to get stat of the folder)
442 - append_message() (but can't be done in the case of POP3 at least)
443 - login() in a case of an authenticated driver.
444 - starttls() in a case of a stream driver, if the procotol supports
445 STARTTLS.
446 - get_message_by_uid() so that the application can remember the message
447 by UID and build its own list of messages.
448
449 * drivers' specific :
450
451 Everything that is specific to the driver will be implemented in this
452 function :
453
454 - parameters()
455*/
456
457struct mailsession_driver {
458 char * sess_name;
459
460 int (* sess_initialize)(mailsession * session);
461 void (* sess_uninitialize)(mailsession * session);
462
463 int (* sess_parameters)(mailsession * session,
464 int id, void * value);
465
466 int (* sess_connect_stream)(mailsession * session, mailstream * s);
467 int (* sess_connect_path)(mailsession * session, char * path);
468
469 int (* sess_starttls)(mailsession * session);
470
471 int (* sess_login)(mailsession * session, char * userid, char * password);
472 int (* sess_logout)(mailsession * session);
473 int (* sess_noop)(mailsession * session);
474
475 /* folders operations */
476
477 int (* sess_build_folder_name)(mailsession * session, char * mb,
478 char * name, char ** result);
479
480 int (* sess_create_folder)(mailsession * session, char * mb);
481 int (* sess_delete_folder)(mailsession * session, char * mb);
482 int (* sess_rename_folder)(mailsession * session, char * mb,
483 char * new_name);
484 int (* sess_check_folder)(mailsession * session);
485 int (* sess_examine_folder)(mailsession * session, char * mb);
486 int (* sess_select_folder)(mailsession * session, char * mb);
487 int (* sess_expunge_folder)(mailsession * session);
488 int (* sess_status_folder)(mailsession * session, char * mb,
489 uint32_t * result_num, uint32_t * result_recent,
490 uint32_t * result_unseen);
491 int (* sess_messages_number)(mailsession * session, char * mb,
492 uint32_t * result);
493 int (* sess_recent_number)(mailsession * session, char * mb,
494 uint32_t * result);
495 int (* sess_unseen_number)(mailsession * session, char * mb,
496 uint32_t * result);
497
498 int (* sess_list_folders)(mailsession * session, char * mb,
499 struct mail_list ** result);
500 int (* sess_lsub_folders)(mailsession * session, char * mb,
501 struct mail_list ** result);
502
503 int (* sess_subscribe_folder)(mailsession * session, char * mb);
504 int (* sess_unsubscribe_folder)(mailsession * session, char * mb);
505
506 /* messages operations */
507
508 int (* sess_append_message)(mailsession * session,
509 char * message, size_t size);
510 int (* sess_copy_message)(mailsession * session,
511 uint32_t num, char * mb);
512 int (* sess_move_message)(mailsession * session,
513 uint32_t num, char * mb);
514
515 int (* sess_get_message)(mailsession * session,
516 uint32_t num, mailmessage ** result);
517
518 int (* sess_get_message_by_uid)(mailsession * session,
519 const char * uid, mailmessage ** result);
520
521 int (* sess_get_messages_list)(mailsession * session,
522 struct mailmessage_list ** result);
523 int (* sess_get_envelopes_list)(mailsession * session,
524 struct mailmessage_list * env_list);
525 int (* sess_remove_message)(mailsession * session, uint32_t num);
526#if 0
527 int (* sess_search_messages)(mailsession * session, char * charset,
528 struct mail_search_key * key,
529 struct mail_search_result ** result);
530#endif
531};
532
533
534/*
535 session is the data structure for a mail session.
536
537 - data is the internal data structure used by the driver
538 It is called when initializing the mailsession structure.
539
540 - driver is the driver used for the session
541*/
542
543struct mailsession {
544 void * sess_data;
545 mailsession_driver * sess_driver;
546};
547
548
549
550
551/*
552 mailmessage_driver is the driver structure to get information from messages.
553
554 - name is the name of the driver
555
556 - initialize() is the function that will initializes a data structure
557 specific to the driver, it returns a value that will be stored
558 in the field data of the mailsession.
559 The field data of the session is the state of the session,
560 the internal data structure used by the driver.
561 It is called when initializing the mailmessage structure with
562 mailmessage_init().
563
564 - uninitialize() frees the structure created with initialize().
565 It will be called by mailmessage_free().
566
567 - flush() will free from memory all temporary structures of the message
568 (for example, the MIME structure of the message).
569
570 - fetch_result_free() will free all strings resulted by fetch() or
571 any fetch_xxx() functions that returns a string.
572
573 - fetch() returns the content of the message (headers and text).
574
575 - fetch_header() returns the content of the headers.
576
577 - fetch_body() returns the message text (message content without headers)
578
579 - fetch_size() returns the size of the message content.
580
581 - get_bodystructure() returns the MIME structure of the message.
582
583 - fetch_section() returns the content of a given MIME part
584
585 - fetch_section_header() returns the header of the message
586 contained by the given MIME part.
587
588 - fetch_section_mime() returns the MIME headers of the
589 given MIME part.
590
591 - fetch_section_body() returns the text (if this is a message, this is the
592 message content without headers) of the given MIME part.
593
594 - fetch_envelope() returns a mailimf_fields structure, with a list of
595 fields chosen by the driver.
596
597 - get_flags() returns a the flags related to the message.
598 When you want to get flags of a message, you have to make sure to
599 call get_flags() at least once before using directly message->flags.
600*/
601
602#define LIBETPAN_MAIL_MESSAGE_CHECK
603
604struct mailmessage_driver {
605 char * msg_name;
606
607 int (* msg_initialize)(mailmessage * msg_info);
608
609 void (* msg_uninitialize)(mailmessage * msg_info);
610
611 void (* msg_flush)(mailmessage * msg_info);
612
613 void (* msg_check)(mailmessage * msg_info);
614
615 void (* msg_fetch_result_free)(mailmessage * msg_info,
616 char * msg);
617
618 int (* msg_fetch)(mailmessage * msg_info,
619 char ** result,
620 size_t * result_len);
621
622 int (* msg_fetch_header)(mailmessage * msg_info,
623 char ** result,
624 size_t * result_len);
625
626 int (* msg_fetch_body)(mailmessage * msg_info,
627 char ** result, size_t * result_len);
628
629 int (* msg_fetch_size)(mailmessage * msg_info,
630 size_t * result);
631
632 int (* msg_get_bodystructure)(mailmessage * msg_info,
633 struct mailmime ** result);
634
635 int (* msg_fetch_section)(mailmessage * msg_info,
636 struct mailmime * mime,
637 char ** result, size_t * result_len);
638
639 int (* msg_fetch_section_header)(mailmessage * msg_info,
640 struct mailmime * mime,
641 char ** result,
642 size_t * result_len);
643
644 int (* msg_fetch_section_mime)(mailmessage * msg_info,
645 struct mailmime * mime,
646 char ** result,
647 size_t * result_len);
648
649 int (* msg_fetch_section_body)(mailmessage * msg_info,
650 struct mailmime * mime,
651 char ** result,
652 size_t * result_len);
653
654 int (* msg_fetch_envelope)(mailmessage * msg_info,
655 struct mailimf_fields ** result);
656
657 int (* msg_get_flags)(mailmessage * msg_info,
658 struct mail_flags ** result);
659};
660
661
662/*
663 mailmessage is a data structure to get information from messages
664
665 - session is the session linked to the given message, it can be NULL
666
667 - driver is the message driver
668
669 - index is the message number
670
671 - uid, when it is not NULL, it means that the folder
672 the folder has persistant message numbers, the string is
673 the unique message number in the folder.
674 uid should be implemented if possible.
675 for drivers where we cannot generate real uid,
676 a suggestion is "AAAA-IIII" where AAAA is some
677 random session number and IIII the content of index field.
678
679 - size, when it is not 0, is the size of the message content.
680
681 - fields, when it is not NULL, are the header fields of the message.
682
683 - flags, when it is not NULL, are the flags related to the message.
684
685 - single_fields, when resolved != 0, is filled with the data of fields.
686
687 - mime, when it is not NULL
688
689 - cached is != 0 when the header fields were read from the cache.
690
691 - data is data specific to the driver, this is internal data structure,
692 some state of the message.
693*/
694
695struct mailmessage {
696 mailsession * msg_session;
697 mailmessage_driver * msg_driver;
698 uint32_t msg_index;
699 char * msg_uid;
700
701 size_t msg_size;
702 struct mailimf_fields * msg_fields;
703 struct mail_flags * msg_flags;
704
705 int msg_resolved;
706 struct mailimf_single_fields msg_single_fields;
707 struct mailmime * msg_mime;
708
709 /* internal data */
710
711 int msg_cached;
712 void * msg_data;
713
714 /*
715 msg_folder field :
716 used to reference the mailfolder, this is a workaround due
717 to the problem with initial conception, where folder notion
718 did not exist.
719 */
720 void * msg_folder;
721 /* user data */
722 void * msg_user_data;
723};
724
725
726/*
727 mailmessage_tree is a node in the messages tree (thread)
728
729 - parent is the parent of the message, it is NULL if the message
730 is the root of the message tree.
731
732 - date is the date of the message in number of second elapsed
733 since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).
734
735 - msg is the message structure that is stored referenced by the node.
736 is msg is NULL, this is a dummy node.
737
738 - children is an array that contains all the children of the node.
739 children are mailmessage_tree structures.
740
741 - is_reply is != 0 when the message is a reply or a forward
742
743 - base_subject is the extracted subject of the message.
744
745 - index is the message number.
746*/
747
748struct mailmessage_tree {
749 struct mailmessage_tree * node_parent;
750 char * node_msgid;
751 time_t node_date;
752 mailmessage * node_msg;
753 carray * node_children; /* array of (struct mailmessage_tree *) */
754
755 /* private, used for threading */
756 int node_is_reply;
757 char * node_base_subject;
758};
759
760
761struct mailmessage_tree *
762mailmessage_tree_new(char * node_msgid, time_t node_date,
763 mailmessage * node_msg);
764
765void mailmessage_tree_free(struct mailmessage_tree * tree);
766
767/*
768 mailmessage_tree_free_recursive
769
770 if you want to release memory of the given tree and all the sub-trees,
771 you can use this function.
772*/
773
774void mailmessage_tree_free_recursive(struct mailmessage_tree * tree);
775
776
777struct generic_message_t {
778 int (* msg_prefetch)(mailmessage * msg_info);
779 void (* msg_prefetch_free)(struct generic_message_t * msg);
780 int msg_fetched;
781 char * msg_message;
782 size_t msg_length;
783 void * msg_data;
784};
785
786
787const char * maildriver_strerror(int err);
788
789#ifdef __cplusplus
790}
791#endif
792
793#endif
diff --git a/kmicromail/libetpan/generic/maildriver_types_helper.c b/kmicromail/libetpan/generic/maildriver_types_helper.c
new file mode 100644
index 0000000..580af7d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver_types_helper.c
@@ -0,0 +1,104 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "maildriver_types_helper.h"
37
38#include "mail.h"
39
40#include "clist.h"
41#include <string.h>
42#include <stdlib.h>
43
44int mail_flags_add_extension(struct mail_flags * flags,
45 char * ext_flag)
46{
47 char * str;
48 int r;
49
50 if (mail_flags_has_extension(flags, ext_flag))
51 return MAIL_NO_ERROR;
52
53 str = strdup(ext_flag);
54 if (str == NULL)
55 return MAIL_ERROR_MEMORY;
56
57 r = clist_append(flags->fl_extension, str);
58 if (r < 0) {
59 free(str);
60 return MAIL_ERROR_MEMORY;
61 }
62
63 return MAIL_NO_ERROR;
64}
65
66int mail_flags_remove_extension(struct mail_flags * flags,
67 char * ext_flag)
68{
69 clistiter * cur;
70
71 cur = clist_begin(flags->fl_extension);
72 while (cur != NULL) {
73 char * flag_name;
74
75 flag_name = clist_content(cur);
76
77 if (strcasecmp(flag_name, ext_flag) == 0) {
78 free(flag_name);
79 cur = clist_delete(flags->fl_extension, cur);
80 }
81 else
82 cur = clist_next(cur);
83 }
84
85 return MAIL_NO_ERROR;
86}
87
88int mail_flags_has_extension(struct mail_flags * flags,
89 char * ext_flag)
90{
91 clistiter * cur;
92
93 for(cur = clist_begin(flags->fl_extension) ; cur != NULL ;
94 cur = clist_next(cur)) {
95 char * flag_name;
96
97 flag_name = clist_content(cur);
98
99 if (strcasecmp(flag_name, ext_flag) == 0)
100 return TRUE;
101 }
102
103 return FALSE;
104}
diff --git a/kmicromail/libetpan/generic/maildriver_types_helper.h b/kmicromail/libetpan/generic/maildriver_types_helper.h
new file mode 100644
index 0000000..2e74dea
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildriver_types_helper.h
@@ -0,0 +1,99 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDRIVER_TYPES_HELPER_H
37
38#define MAILDRIVER_TYPES_HELPER_H
39
40#include <libetpan/maildriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 mail_flags_add_extension adds the given flag if it does not exists in
48 the flags.
49
50 @param flags this is the flag to change
51
52 @param ext_flag this is the name of an extension flag
53 the given flag name is duplicated and is no more needed after
54 the function call.
55
56 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
57 on error
58*/
59
60int mail_flags_add_extension(struct mail_flags * flags,
61 char * ext_flag);
62
63/*
64 mail_flags_remove_extension removes the given flag if it does not exists in
65 the flags.
66
67 @param flags this is the flag to change
68
69 @param ext_flag this is the name of an extension flag
70 the given flag name is no more needed after the function call.
71
72 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
73 on error
74*/
75
76int mail_flags_remove_extension(struct mail_flags * flags,
77 char * ext_flag);
78
79/*
80 mail_flags_has_extension returns 1 if the flags is in the given flags,
81 0 is returned otherwise.
82
83 @param flags this is the flag to change
84
85 @param ext_flag this is the name of an extension flag
86 the given flag name is no more needed after the function call.
87
88 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
89 on error
90*/
91
92int mail_flags_has_extension(struct mail_flags * flags,
93 char * ext_flag);
94
95#ifdef __cplusplus
96}
97#endif
98
99#endif
diff --git a/kmicromail/libetpan/generic/mailfolder.c b/kmicromail/libetpan/generic/mailfolder.c
new file mode 100644
index 0000000..2ddc37d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailfolder.c
@@ -0,0 +1,96 @@
1#include "mailfolder.h"
2
3#include "maildriver.h"
4
5int mailfolder_noop(struct mailfolder * folder)
6{
7 return mailsession_noop(folder->fld_session);
8}
9
10int mailfolder_check(struct mailfolder * folder)
11{
12 return mailsession_check_folder(folder->fld_session);
13}
14
15int mailfolder_expunge(struct mailfolder * folder)
16{
17 return mailsession_expunge_folder(folder->fld_session);
18}
19
20int mailfolder_status(struct mailfolder * folder,
21 uint32_t * result_messages, uint32_t * result_recent,
22 uint32_t * result_unseen)
23{
24 return mailsession_status_folder(folder->fld_session,
25 folder->fld_pathname, result_messages,
26 result_recent, result_unseen);
27}
28
29int mailfolder_append_message(struct mailfolder * folder,
30 char * message, size_t size)
31{
32 return mailsession_append_message(folder->fld_session, message, size);
33}
34
35int mailfolder_get_messages_list(struct mailfolder * folder,
36 struct mailmessage_list ** result)
37{
38 int r;
39 struct mailmessage_list * msg_list;
40 unsigned int i;
41
42 r = mailsession_get_messages_list(folder->fld_session, &msg_list);
43 if (r != MAIL_NO_ERROR)
44 return r;
45
46 for(i = 0 ; i < carray_count(msg_list->msg_tab) ; i ++) {
47 mailmessage * msg;
48
49 msg = carray_get(msg_list->msg_tab, i);
50 msg->msg_folder = folder;
51 }
52
53 * result = msg_list;
54
55 return MAIL_NO_ERROR;
56}
57
58int mailfolder_get_envelopes_list(struct mailfolder * folder,
59 struct mailmessage_list * result)
60{
61 return mailsession_get_envelopes_list(folder->fld_session, result);
62}
63
64int mailfolder_get_message(struct mailfolder * folder,
65 uint32_t num, mailmessage ** result)
66{
67 mailmessage * msg;
68 int r;
69
70 r = mailsession_get_message(folder->fld_session, num, &msg);
71 if (r != MAIL_NO_ERROR)
72 return r;
73
74 msg->msg_folder = folder;
75
76 * result = msg;
77
78 return MAIL_NO_ERROR;
79}
80
81int mailfolder_get_message_by_uid(struct mailfolder * folder,
82 const char * uid, mailmessage ** result)
83{
84 mailmessage * msg;
85 int r;
86
87 r = mailsession_get_message_by_uid(folder->fld_session, uid, &msg);
88 if (r != MAIL_NO_ERROR)
89 return r;
90
91 msg->msg_folder = folder;
92
93 * result = msg;
94
95 return MAIL_NO_ERROR;
96}
diff --git a/kmicromail/libetpan/generic/mailfolder.h b/kmicromail/libetpan/generic/mailfolder.h
new file mode 100644
index 0000000..3ecad23
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailfolder.h
@@ -0,0 +1,32 @@
1#ifndef MAILFOLDER_H
2
3#define MAILFOLDER_H
4
5#include "mailstorage_types.h"
6
7int mailfolder_noop(struct mailfolder * folder);
8
9int mailfolder_check(struct mailfolder * folder);
10
11int mailfolder_expunge(struct mailfolder * folder);
12
13int mailfolder_status(struct mailfolder * folder,
14 uint32_t * result_messages, uint32_t * result_recent,
15 uint32_t * result_unseen);
16
17int mailfolder_append_message(struct mailfolder * folder,
18 char * message, size_t size);
19
20int mailfolder_get_messages_list(struct mailfolder * folder,
21 struct mailmessage_list ** result);
22
23int mailfolder_get_envelopes_list(struct mailfolder * folder,
24 struct mailmessage_list * result);
25
26int mailfolder_get_message(struct mailfolder * folder,
27 uint32_t num, mailmessage ** result);
28
29int mailfolder_get_message_by_uid(struct mailfolder * folder,
30 const char * uid, mailmessage ** result);
31
32#endif
diff --git a/kmicromail/libetpan/generic/mailmessage.c b/kmicromail/libetpan/generic/mailmessage.c
new file mode 100644
index 0000000..9d3884f
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailmessage.c
@@ -0,0 +1,240 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailmessage.h"
37
38#include "mail.h"
39
40#include <string.h>
41
42int mailmessage_init(mailmessage * msg_info,
43 mailsession * msg_session,
44 mailmessage_driver * msg_driver,
45 uint32_t msg_index, size_t msg_size)
46{
47 int r;
48 int res;
49
50 msg_info->msg_driver = msg_driver;
51 msg_info->msg_session = msg_session;
52 msg_info->msg_index = msg_index;
53 msg_info->msg_uid = NULL;
54
55 msg_info->msg_cached = FALSE;
56 msg_info->msg_size = msg_size;
57 msg_info->msg_fields = NULL;
58 memset(&msg_info->msg_single_fields, 0,
59 sizeof(struct mailimf_single_fields));
60 msg_info->msg_resolved = FALSE;
61 msg_info->msg_flags = NULL;
62
63 msg_info->msg_mime = NULL;
64 msg_info->msg_data = NULL;
65 msg_info->msg_folder = NULL;
66 msg_info->msg_user_data = NULL;
67
68 if (msg_driver->msg_initialize != NULL) {
69 r = msg_driver->msg_initialize(msg_info);
70 if (r != MAIL_NO_ERROR) {
71 res = r;
72 goto err;
73 }
74 }
75
76 return MAIL_NO_ERROR;
77
78 err:
79 msg_info->msg_driver = NULL;
80 msg_info->msg_session = NULL;
81 return res;
82}
83
84int mailmessage_flush(mailmessage * msg_info)
85{
86 if (msg_info->msg_driver->msg_flush == NULL)
87 return MAIL_ERROR_NOT_IMPLEMENTED;
88
89 msg_info->msg_driver->msg_flush(msg_info);
90
91 return MAIL_NO_ERROR;
92}
93
94int mailmessage_check(mailmessage * msg_info)
95{
96 if (msg_info->msg_driver->msg_check == NULL)
97 return MAIL_ERROR_NOT_IMPLEMENTED;
98
99 msg_info->msg_driver->msg_check(msg_info);
100
101 return MAIL_NO_ERROR;
102}
103
104int mailmessage_fetch_result_free(mailmessage * msg_info,
105 char * msg)
106{
107 if (msg_info->msg_driver->msg_fetch_result_free == NULL)
108 return MAIL_ERROR_NOT_IMPLEMENTED;
109
110 msg_info->msg_driver->msg_fetch_result_free(msg_info, msg);
111
112 return MAIL_NO_ERROR;
113}
114
115int mailmessage_fetch(mailmessage * msg_info,
116 char ** result,
117 size_t * result_len)
118{
119 if (msg_info->msg_driver->msg_fetch == NULL)
120 return MAIL_ERROR_NOT_IMPLEMENTED;
121
122 return msg_info->msg_driver->msg_fetch(msg_info, result, result_len);
123}
124
125int mailmessage_fetch_header(mailmessage * msg_info,
126 char ** result,
127 size_t * result_len)
128{
129 if (msg_info->msg_driver->msg_fetch_header == NULL)
130 return MAIL_ERROR_NOT_IMPLEMENTED;
131
132 return msg_info->msg_driver->msg_fetch_header(msg_info, result, result_len);
133}
134
135int mailmessage_fetch_body(mailmessage * msg_info,
136 char ** result, size_t * result_len)
137{
138 if (msg_info->msg_driver->msg_fetch_body == NULL)
139 return MAIL_ERROR_NOT_IMPLEMENTED;
140
141 return msg_info->msg_driver->msg_fetch_body(msg_info, result, result_len);
142}
143
144int mailmessage_fetch_size(mailmessage * msg_info,
145 size_t * result)
146{
147 if (msg_info->msg_driver->msg_fetch_size == NULL)
148 return MAIL_ERROR_NOT_IMPLEMENTED;
149
150 return msg_info->msg_driver->msg_fetch_size(msg_info, result);
151}
152
153int mailmessage_get_bodystructure(mailmessage * msg_info,
154 struct mailmime ** result)
155{
156 if (msg_info->msg_driver->msg_get_bodystructure == NULL)
157 return MAIL_ERROR_NOT_IMPLEMENTED;
158
159 return msg_info->msg_driver->msg_get_bodystructure(msg_info, result);
160}
161
162int mailmessage_fetch_section(mailmessage * msg_info,
163 struct mailmime * mime,
164 char ** result, size_t * result_len)
165{
166 if (msg_info->msg_driver->msg_fetch_section == NULL)
167 return MAIL_ERROR_NOT_IMPLEMENTED;
168
169 return msg_info->msg_driver->msg_fetch_section(msg_info, mime, result, result_len);
170}
171
172int mailmessage_fetch_section_header(mailmessage * msg_info,
173 struct mailmime * mime,
174 char ** result,
175 size_t * result_len)
176{
177 if (msg_info->msg_driver->msg_fetch_section_header == NULL)
178 return MAIL_ERROR_NOT_IMPLEMENTED;
179
180 return msg_info->msg_driver->msg_fetch_section_header(msg_info, mime,
181 result, result_len);
182}
183
184int mailmessage_fetch_section_mime(mailmessage * msg_info,
185 struct mailmime * mime,
186 char ** result,
187 size_t * result_len)
188{
189 if (msg_info->msg_driver->msg_fetch_section_mime == NULL)
190 return MAIL_ERROR_NOT_IMPLEMENTED;
191
192 return msg_info->msg_driver->msg_fetch_section_mime(msg_info, mime,
193 result, result_len);
194}
195
196int mailmessage_fetch_section_body(mailmessage * msg_info,
197 struct mailmime * mime,
198 char ** result,
199 size_t * result_len)
200{
201 if (msg_info->msg_driver->msg_fetch_section_body == NULL)
202 return MAIL_ERROR_NOT_IMPLEMENTED;
203
204 return msg_info->msg_driver->msg_fetch_section_body(msg_info, mime,
205 result, result_len);
206}
207
208int mailmessage_fetch_envelope(mailmessage * msg_info,
209 struct mailimf_fields ** result)
210{
211 if (msg_info->msg_driver->msg_fetch_envelope == NULL)
212 return MAIL_ERROR_NOT_IMPLEMENTED;
213
214 return msg_info->msg_driver->msg_fetch_envelope(msg_info, result);
215}
216
217int mailmessage_get_flags(mailmessage * msg_info,
218 struct mail_flags ** result)
219{
220 struct mail_flags * dummy;
221
222 if (msg_info->msg_driver->msg_get_flags == NULL)
223 return MAIL_ERROR_NOT_IMPLEMENTED;
224
225 if (result != NULL)
226 return msg_info->msg_driver->msg_get_flags(msg_info, result);
227 else
228 return msg_info->msg_driver->msg_get_flags(msg_info, &dummy);
229}
230
231void mailmessage_resolve_single_fields(mailmessage * msg_info)
232{
233 if (!msg_info->msg_resolved) {
234 if (msg_info->msg_fields != NULL) {
235 mailimf_single_fields_init(&msg_info->msg_single_fields,
236 msg_info->msg_fields);
237 msg_info->msg_resolved = TRUE;
238 }
239 }
240}
diff --git a/kmicromail/libetpan/generic/mailmessage.h b/kmicromail/libetpan/generic/mailmessage.h
new file mode 100644
index 0000000..df9b790
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailmessage.h
@@ -0,0 +1,379 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include <libetpan/mailmessage_types.h>
37
38#ifndef MAILMESSAGE_H
39
40#define MAILMESSAGE_H
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 mailmessage_new
48
49 This function will initializes a new empty message.
50
51 @return a new empty message will be returned.
52*/
53
54mailmessage * mailmessage_new(void);
55
56/*
57 mailmessage_free
58
59 This function will release the memory used by this message.
60*/
61
62void mailmessage_free(mailmessage * info);
63
64/*
65 mailmessage_init
66
67 This function will initializes a mailmessage structure
68 with a message from a given session.
69
70 @param msg_info This is the message to initialize.
71
72 @param session This is the source session of the message. It
73 can be NULL if the message does not get the information
74 through the session.
75
76 @param driver This is the driver to use for the message.
77
78 @param index This is the message number in the session. 0 can
79 be given if the message is not attached to a session.
80
81 @param size is an optional parameter, 0 can be given.
82 This is informational. This is the size of message content.
83
84 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
85 on error
86*/
87
88int mailmessage_init(mailmessage * msg_info,
89 mailsession * session,
90 mailmessage_driver * driver,
91 uint32_t index, size_t size);
92
93/*
94 mailmessage_flush
95
96 This function will release all the temporary resources that are not
97 necessary to use the mailmessage structure from memory. These
98 resources are for example cached information, such as the MIME
99 structure.
100
101 @param info is the message to clean.
102
103 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
104 on error. We can assume that MAIL_NO_ERROR is always returned.
105*/
106
107int mailmessage_flush(mailmessage * info);
108
109/*
110 mailmessage_check
111
112 This function will notify the new value of the flags to the session,
113 it must be called before mailsession_check_folder() in case the flags have
114 been changed.
115
116 @param info is the message to checkpoint.
117
118 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
119 on error. We can assume that MAIL_NO_ERROR is always returned.
120*/
121
122int mailmessage_check(mailmessage * info);
123
124/*
125 mailmessage_fetch_result_free
126
127 This function releases the memory used by a message returned
128 by any of the fetch function that returns a (char *).
129
130 @param msg_info is the message which the given buffer is from.
131
132 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
133 on error. We can assume that MAIL_NO_ERROR is always returned.
134*/
135
136int mailmessage_fetch_result_free(mailmessage * msg_info,
137 char * msg);
138
139/*
140 mailmessage_fetch
141
142 This function returns the content of the message (headers and text).
143
144 @param msg_info is the message from which we want to fetch information.
145
146 @param result The content of the message is returned in (* result)
147
148 @param result_len The length of the returned string is stored
149 in (* result_len).
150
151 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
152 on error.
153*/
154
155int mailmessage_fetch(mailmessage * msg_info,
156 char ** result,
157 size_t * result_len);
158
159/*
160 mailmessage_fetch_header
161
162 This function returns the header of the message as a string.
163
164 @param msg_info is the message from which we want to fetch information.
165
166 @param result The header of the message is returned in (* result)
167
168 @param result_len The length of the returned string is stored
169 in (* result_len).
170
171 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
172 on error.
173*/
174
175int mailmessage_fetch_header(mailmessage * msg_info,
176 char ** result,
177 size_t * result_len);
178
179/*
180 mailmessage_fetch_body
181
182 This function returns the content of the message (without headers).
183
184 @param msg_info is the message from which we want to fetch information.
185 @param result The message text (without headers) is returned
186 in (* result)
187 @param result_len The length of the returned string is stored
188 in (* result_len).
189
190 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
191 on error.
192*/
193
194int mailmessage_fetch_body(mailmessage * msg_info,
195 char ** result, size_t * result_len);
196
197/*
198 mailmessage_fetch_size
199
200 This function returns the size of the message content.
201
202 @param msg_info is the message from which we want to fetch information.
203
204 @param result The length of the message content is stored in (* result).
205
206 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
207 on error.
208*/
209
210int mailmessage_fetch_size(mailmessage * msg_info,
211 size_t * result);
212
213/*
214 mailmessage_get_bodystructure
215
216 This functions returns the MIME structure of the message.
217 The returned information MUST not be freed by hand. It is freed by
218 mailmessage_flush() or mailmessage_free().
219
220 @param msg_info is the message from which we want to fetch information.
221
222 @param result The MIME structure is stored in (* result).
223
224 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
225 on error.
226*/
227
228int mailmessage_get_bodystructure(mailmessage * msg_info,
229 struct mailmime ** result);
230
231/*
232 mailmessage_fetch_section
233
234 This function returns the content of a MIME part.
235
236 @param msg_info is the message from which we want to fetch information.
237
238 @param mime is the MIME part identifier.
239
240 @param result The content is returned in (* result)
241
242 @param result_len The length of the returned string is stored
243 in (* result_len).
244
245 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
246 on error.
247 */
248
249int mailmessage_fetch_section(mailmessage * msg_info,
250 struct mailmime * mime,
251 char ** result, size_t * result_len);
252
253/*
254 mailmessage_fetch_section_header
255
256 This function returns the header of the message contained
257 in the given MIME part.
258
259 @param msg_info is the message from which we want to fetch information.
260
261 @param mime is the MIME part identifier.
262
263 @param result The header is returned in (* result)
264
265 @param result_len The length of the returned string is stored
266 in (* result_len).
267
268 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
269 on error.
270*/
271
272int mailmessage_fetch_section_header(mailmessage * msg_info,
273 struct mailmime * mime,
274 char ** result,
275 size_t * result_len);
276
277/*
278 mailmessage_fetch_section_mime
279
280 This function returns the MIME header of the given MIME part.
281
282 @param msg_info is the message from which we want to fetch information.
283
284 @param mime is the MIME part identifier.
285
286 @param result The MIME header is returned in (* result)
287
288 @param result_len The length of the returned string is stored
289 in (* result_len).
290
291 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
292 on error.
293*/
294
295int mailmessage_fetch_section_mime(mailmessage * msg_info,
296 struct mailmime * mime,
297 char ** result,
298 size_t * result_len);
299
300/*
301 mailmessage_fetch_section_body
302
303 This function returns the text part of the message contained
304 in the given MIME part.
305
306 @param msg_info is the message from which we want to fetch information.
307
308 @param mime is the MIME part identifier.
309
310 @param result The message text is returned in (* result)
311
312 @param result_len The length of the returned string is stored
313 in (* result_len).
314
315 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
316 on error.
317 */
318
319int mailmessage_fetch_section_body(mailmessage * msg_info,
320 struct mailmime * mime,
321 char ** result,
322 size_t * result_len);
323
324/*
325 mailmessage_fetch_envelope
326
327 This function returns a list of parsed fields of the message,
328 chosen by the driver.
329 The returned structure must be freed with mailimf_fields_free().
330
331 @param msg_info is the message from which we want to fetch information.
332
333 @param result The headers list is returned in (* result)
334
335 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
336 on error.
337 */
338
339int mailmessage_fetch_envelope(mailmessage * msg_info,
340 struct mailimf_fields ** result);
341
342
343/*
344 mailmessage_get_flags
345
346 This function returns the flags related to the message.
347 The returned information MUST not be freed by hand. It is freed by
348 mailmessage_free().
349
350 @param msg_info is the message from which we want to fetch information.
351
352 @param result The flags are stored in (* result).
353
354 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
355 on error.
356*/
357
358int mailmessage_get_flags(mailmessage * msg_info,
359 struct mail_flags ** result);
360
361/*
362 mailmessage_resolve_single_fields
363
364 This function will use the fields information to fill the single_fields
365 structure in the mailmessage structure.
366
367 @param msg_info This is the msg_info to process.
368
369 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
370 on error.
371*/
372
373void mailmessage_resolve_single_fields(mailmessage * msg_info);
374
375#ifdef __cplusplus
376}
377#endif
378
379#endif
diff --git a/kmicromail/libetpan/generic/mailmessage_tools.c b/kmicromail/libetpan/generic/mailmessage_tools.c
new file mode 100644
index 0000000..e66f6ba
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailmessage_tools.c
@@ -0,0 +1,600 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailmessage_tools.h"
37#include "mailmessage.h"
38
39#include <stdlib.h>
40
41#include "maildriver.h"
42#include "maildriver_tools.h"
43
44int
45mailmessage_generic_initialize(mailmessage * msg_info)
46{
47 struct generic_message_t * msg;
48
49 msg = malloc(sizeof(* msg));
50
51 if (msg == NULL) {
52 return MAIL_ERROR_MEMORY;
53 }
54
55 msg->msg_fetched = 0;
56 msg->msg_message = NULL;
57 msg->msg_length = 0;
58
59 msg->msg_prefetch = NULL;
60 msg->msg_prefetch_free = NULL;
61 msg->msg_data = NULL;
62
63 msg_info->msg_data = msg;
64
65 return MAIL_NO_ERROR;
66}
67
68void mailmessage_generic_flush(mailmessage * msg_info)
69{
70 struct generic_message_t * msg;
71
72 if (msg_info->msg_mime != NULL) {
73 mailmime_free(msg_info->msg_mime);
74 msg_info->msg_mime = NULL;
75 }
76 msg = msg_info->msg_data;
77 if (msg != NULL) {
78 if (msg->msg_prefetch_free != NULL)
79 msg->msg_prefetch_free(msg);
80 msg->msg_fetched = 0;
81 }
82}
83
84void mailmessage_generic_uninitialize(mailmessage * msg_info)
85{
86 struct generic_message_t * msg;
87
88 mailmessage_generic_flush(msg_info);
89
90 msg = msg_info->msg_data;
91 msg_info->msg_data = NULL;
92 free(msg);
93}
94
95static inline int
96mailmessage_generic_prefetch(mailmessage * msg_info)
97{
98 struct generic_message_t * msg;
99 int r;
100
101 msg = msg_info->msg_data;
102
103 if (msg->msg_fetched)
104 return MAIL_NO_ERROR;
105
106#if 0
107 if (msg->message != NULL)
108 return MAIL_NO_ERROR;
109#endif
110
111 r = msg->msg_prefetch(msg_info);
112 if (r != MAIL_NO_ERROR)
113 return r;
114
115 msg->msg_fetched = 1;
116
117 return MAIL_NO_ERROR;
118}
119
120static int
121mailmessage_generic_prefetch_bodystructure(mailmessage * msg_info)
122{
123 size_t length;
124 char * message;
125 size_t cur_token;
126 struct mailmime * mime;
127 int r;
128 int res;
129 struct generic_message_t * msg;
130
131 if (msg_info->msg_mime != NULL) {
132 /* it has already been fetched */
133 return MAIL_NO_ERROR;
134 }
135
136#if 0
137 msg = msg_info->data;
138 if (msg->message == NULL) {
139 r = mailmessage_generic_prefetch(msg_info);
140 if (r != MAIL_NO_ERROR) {
141 res = r;
142 goto err;
143 }
144 }
145#endif
146 r = mailmessage_generic_prefetch(msg_info);
147 if (r != MAIL_NO_ERROR) {
148 res = r;
149 goto err;
150 }
151
152 msg = msg_info->msg_data;
153 message = msg->msg_message;
154 length = msg->msg_length;
155 cur_token = 0;
156 r = mailmime_parse(message, length, &cur_token, &mime);
157 if (r != MAILIMF_NO_ERROR) {
158 res = MAIL_ERROR_PARSE;
159 goto err;
160 }
161
162 msg_info->msg_mime = mime;
163
164 return MAIL_NO_ERROR;
165
166 err:
167 return res;
168}
169
170void
171mailmessage_generic_fetch_result_free(mailmessage * msg_info, char * msg)
172{
173 int r;
174
175 r = mmap_string_unref(msg);
176}
177
178int mailmessage_generic_fetch(mailmessage * msg_info,
179 char ** result,
180 size_t * result_len)
181{
182 int r;
183 char * message;
184 size_t cur_token;
185 size_t length;
186 MMAPString * mmapstr;
187 int res;
188 struct generic_message_t * msg;
189
190 msg = msg_info->msg_data;
191 r = mailmessage_generic_prefetch(msg_info);
192 if (r != MAIL_NO_ERROR) {
193 res = r;
194 goto err;
195 }
196
197 message = msg->msg_message;
198 length = msg->msg_length;
199 cur_token = 0;
200
201 mmapstr = mmap_string_new_len(message, length);
202 if (mmapstr == NULL) {
203 res = MAIL_ERROR_MEMORY;
204 goto err;
205 }
206
207 r = mmap_string_ref(mmapstr);
208 if (r < 0) {
209 res = MAIL_ERROR_MEMORY;
210 goto free_mmap;
211 }
212
213 * result = mmapstr->str;
214 * result_len = length;
215
216 return MAIL_NO_ERROR;
217
218 free_mmap:
219 mmap_string_free(mmapstr);
220 err:
221 return res;
222}
223
224int mailmessage_generic_fetch_header(mailmessage * msg_info,
225 char ** result,
226 size_t * result_len)
227{
228 int r;
229 char * message;
230 size_t cur_token;
231 size_t length;
232 MMAPString * mmapstr;
233 char * headers;
234 int res;
235 struct generic_message_t * msg;
236
237 msg = msg_info->msg_data;
238 r = mailmessage_generic_prefetch(msg_info);
239 if (r != MAIL_NO_ERROR) {
240 res = r;
241 goto err;
242 }
243
244 message = msg->msg_message;
245 length = msg->msg_length;
246 cur_token = 0;
247
248 while (1) {
249 r = mailimf_ignore_field_parse(message, length, &cur_token);
250 if (r == MAILIMF_NO_ERROR) {
251 /* do nothing */
252 }
253 else
254 break;
255 }
256 mailimf_crlf_parse(message, length, &cur_token);
257
258 mmapstr = mmap_string_new_len(message, cur_token);
259 if (mmapstr == NULL) {
260 res = MAIL_ERROR_MEMORY;
261 goto err;
262 }
263
264 r = mmap_string_ref(mmapstr);
265 if (r < 0) {
266 res = MAIL_ERROR_MEMORY;
267 goto free_mmap;
268 }
269
270 headers = mmapstr->str;
271
272 * result = headers;
273 * result_len = cur_token;
274
275 return MAIL_NO_ERROR;
276
277 free_mmap:
278 mmap_string_free(mmapstr);
279 err:
280 return res;
281}
282
283int mailmessage_generic_fetch_body(mailmessage * msg_info,
284 char ** result, size_t * result_len)
285{
286 int r;
287 char * message;
288 size_t cur_token;
289 MMAPString * mmapstr;
290 size_t length;
291 int res;
292 struct generic_message_t * msg;
293
294 msg = msg_info->msg_data;
295 r = mailmessage_generic_prefetch(msg_info);
296 if (r != MAIL_NO_ERROR) {
297 res = r;
298 goto err;
299 }
300
301 message = msg->msg_message;
302 length = msg->msg_length;
303 cur_token = 0;
304
305 while (1) {
306 r = mailimf_ignore_field_parse(message, length, &cur_token);
307 if (r == MAILIMF_NO_ERROR) {
308 /* do nothing */
309 }
310 else
311 break;
312 }
313 mailimf_crlf_parse(message, length, &cur_token);
314
315 mmapstr = mmap_string_new_len(message + cur_token, length - cur_token);
316 if (mmapstr == NULL) {
317 res = MAIL_ERROR_MEMORY;
318 goto err;
319 }
320
321 r = mmap_string_ref(mmapstr);
322 if (r < 0) {
323 res = MAIL_ERROR_MEMORY;
324 goto free_mmap;
325 }
326
327 * result = mmapstr->str;
328 * result_len = length - cur_token;
329
330 return MAIL_NO_ERROR;
331
332 free_mmap:
333 mmap_string_free(mmapstr);
334 err:
335 return res;
336}
337
338
339
340
341int
342mailmessage_generic_get_bodystructure(mailmessage * msg_info,
343 struct mailmime ** result)
344{
345 int r;
346
347 r = mailmessage_generic_prefetch_bodystructure(msg_info);
348 if (r != MAIL_NO_ERROR)
349 return r;
350
351 * result = msg_info->msg_mime;
352
353 return MAIL_NO_ERROR;
354}
355
356
357
358
359int
360mailmessage_generic_fetch_section(mailmessage * msg_info,
361 struct mailmime * mime,
362 char ** result, size_t * result_len)
363{
364 MMAPString * mmapstr;
365 int r;
366 int res;
367
368 mmapstr = mmap_string_new_len(mime->mm_body->dt_data.dt_text.dt_data,
369 mime->mm_body->dt_data.dt_text.dt_length);
370 if (mmapstr == NULL) {
371 res = MAIL_ERROR_MEMORY;
372 goto err;
373 }
374
375 r = mmap_string_ref(mmapstr);
376 if (r < 0) {
377 res = MAIL_ERROR_MEMORY;
378 goto free_mmap;
379 }
380
381 * result = mmapstr->str;
382 * result_len = mmapstr->len;
383
384 return MAIL_NO_ERROR;
385
386 free_mmap:
387 mmap_string_free(mmapstr);
388 err:
389 return res;
390}
391
392int
393mailmessage_generic_fetch_section_header(mailmessage * msg_info,
394 struct mailmime * mime,
395 char ** result,
396 size_t * result_len)
397{
398 MMAPString * mmapstr;
399 int r;
400 int res;
401 size_t cur_token;
402
403 /* skip mime */
404
405 cur_token = 0;
406
407 if (mime->mm_type == MAILMIME_MESSAGE) {
408
409 while (1) {
410 r = mailimf_ignore_field_parse(mime->mm_body->dt_data.dt_text.dt_data,
411 mime->mm_body->dt_data.dt_text.dt_length, &cur_token);
412 if (r == MAILIMF_NO_ERROR) {
413 /* do nothing */
414 }
415 else
416 break;
417 }
418
419 r = mailimf_crlf_parse(mime->mm_body->dt_data.dt_text.dt_data,
420 mime->mm_body->dt_data.dt_text.dt_length, &cur_token);
421 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
422 res = maildriver_imf_error_to_mail_error(r);
423 goto err;
424 }
425 }
426
427 mmapstr = mmap_string_new_len(mime->mm_body->dt_data.dt_text.dt_data,
428 cur_token);
429 if (mmapstr == NULL) {
430 res = MAIL_ERROR_MEMORY;
431 goto err;
432 }
433
434 r = mmap_string_ref(mmapstr);
435 if (r < 0) {
436 res = MAIL_ERROR_MEMORY;
437 goto free_mmap;
438 }
439
440 * result = mmapstr->str;
441 * result_len = mmapstr->len;
442
443 return MAIL_NO_ERROR;
444
445 free_mmap:
446 mmap_string_free(mmapstr);
447 err:
448 return res;
449}
450
451int
452mailmessage_generic_fetch_section_mime(mailmessage * msg_info,
453 struct mailmime * mime,
454 char ** result,
455 size_t * result_len)
456{
457 MMAPString * mmapstr;
458 int r;
459 int res;
460 size_t cur_token;
461
462 cur_token = 0;
463
464 /* skip header */
465
466 while (1) {
467 r = mailimf_ignore_field_parse(mime->mm_mime_start,
468 mime->mm_length, &cur_token);
469 if (r == MAILIMF_NO_ERROR) {
470 /* do nothing */
471 }
472 else
473 break;
474 }
475
476 r = mailimf_crlf_parse(mime->mm_mime_start, mime->mm_length, &cur_token);
477 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
478 res = maildriver_imf_error_to_mail_error(r);
479 goto err;
480 }
481
482 mmapstr = mmap_string_new_len(mime->mm_mime_start, cur_token);
483 if (mmapstr == NULL) {
484 res = MAIL_ERROR_MEMORY;
485 goto err;
486 }
487
488 r = mmap_string_ref(mmapstr);
489 if (r < 0) {
490 res = MAIL_ERROR_MEMORY;
491 goto free_mmap;
492 }
493
494 * result = mmapstr->str;
495 * result_len = mmapstr->len;
496
497 return MAIL_NO_ERROR;
498
499 free_mmap:
500 mmap_string_free(mmapstr);
501 err:
502 return res;
503}
504
505int
506mailmessage_generic_fetch_section_body(mailmessage * msg_info,
507 struct mailmime * mime,
508 char ** result,
509 size_t * result_len)
510{
511 MMAPString * mmapstr;
512 int r;
513 int res;
514 size_t cur_token;
515
516 cur_token = 0;
517
518 if (mime->mm_type == MAILMIME_MESSAGE) {
519
520 /* skip header */
521
522 while (1) {
523 r = mailimf_ignore_field_parse(mime->mm_body->dt_data.dt_text.dt_data,
524 mime->mm_body->dt_data.dt_text.dt_length, &cur_token);
525 if (r == MAILIMF_NO_ERROR) {
526 /* do nothing */
527 }
528 else
529 break;
530 }
531
532 r = mailimf_crlf_parse(mime->mm_body->dt_data.dt_text.dt_data,
533 mime->mm_body->dt_data.dt_text.dt_length, &cur_token);
534 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
535 res = maildriver_imf_error_to_mail_error(r);
536 goto err;
537 }
538 }
539
540 mmapstr = mmap_string_new_len(mime->mm_body->dt_data.dt_text.dt_data +
541 cur_token, mime->mm_body->dt_data.dt_text.dt_length - cur_token);
542 if (mmapstr == NULL) {
543 res = MAIL_ERROR_MEMORY;
544 goto err;
545 }
546
547 r = mmap_string_ref(mmapstr);
548 if (r < 0) {
549 res = MAIL_ERROR_MEMORY;
550 goto free_mmap;
551 }
552
553 * result = mmapstr->str;
554 * result_len = mmapstr->len;
555
556 return MAIL_NO_ERROR;
557
558 free_mmap:
559 mmap_string_free(mmapstr);
560 err:
561 return res;
562}
563
564int mailmessage_generic_fetch_envelope(mailmessage * msg_info,
565 struct mailimf_fields ** result)
566{
567 int r;
568 int res;
569 size_t cur_token;
570 char * header;
571 size_t length;
572 struct mailimf_fields * fields;
573
574 r = mailmessage_fetch_header(msg_info, &header, &length);
575 if (r != MAIL_NO_ERROR) {
576 res = r;
577 goto err;
578 }
579
580 cur_token = 0;
581
582 r = mailimf_envelope_fields_parse(header, length, &cur_token,
583 &fields);
584 if (r != MAILIMF_NO_ERROR) {
585 res = maildriver_imf_error_to_mail_error(r);
586 goto free;
587 /* do nothing */
588 }
589
590 mailmessage_fetch_result_free(msg_info, header);
591
592 * result = fields;
593
594 return MAIL_NO_ERROR;
595
596 free:
597 mailmessage_fetch_result_free(msg_info, header);
598 err:
599 return res;
600}
diff --git a/kmicromail/libetpan/generic/mailmessage_tools.h b/kmicromail/libetpan/generic/mailmessage_tools.h
new file mode 100644
index 0000000..a4f9b1e
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailmessage_tools.h
@@ -0,0 +1,103 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMESSAGE_TOOLS_H
37
38#define MAILMESSAGE_TOOLS_H
39
40#include "mailmessage_types.h"
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46int
47mailmessage_generic_initialize(mailmessage *
48 msg_info);
49
50void mailmessage_generic_uninitialize(mailmessage *
51 msg_info);
52
53void mailmessage_generic_flush(mailmessage * msg_info);
54
55void mailmessage_generic_fetch_result_free(mailmessage * msg_info,
56 char * msg);
57
58int mailmessage_generic_fetch(mailmessage * msg_info,
59 char ** result,
60 size_t * result_len);
61
62int mailmessage_generic_fetch_header(mailmessage * msg_info,
63 char ** result,
64 size_t * result_len);
65
66int mailmessage_generic_fetch_body(mailmessage * msg_info,
67 char ** result, size_t * result_len);
68
69int mailmessage_generic_get_bodystructure(mailmessage *
70 msg_info,
71 struct mailmime ** result);
72
73int
74mailmessage_generic_fetch_section(mailmessage * msg_info,
75 struct mailmime * mime,
76 char ** result, size_t * result_len);
77
78int
79mailmessage_generic_fetch_section_header(mailmessage * msg_info,
80 struct mailmime * mime,
81 char ** result,
82 size_t * result_len);
83
84int
85mailmessage_generic_fetch_section_mime(mailmessage * msg_info,
86 struct mailmime * mime,
87 char ** result,
88 size_t * result_len);
89
90int
91mailmessage_generic_fetch_section_body(mailmessage * msg_info,
92 struct mailmime * mime,
93 char ** result,
94 size_t * result_len);
95
96int mailmessage_generic_fetch_envelope(mailmessage * msg_info,
97 struct mailimf_fields ** result);
98
99#ifdef __cplusplus
100}
101#endif
102
103#endif
diff --git a/kmicromail/libetpan/generic/mailmessage_types.c b/kmicromail/libetpan/generic/mailmessage_types.c
new file mode 100644
index 0000000..9f8c355
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailmessage_types.c
@@ -0,0 +1,92 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailmessage_types.h"
37
38#include "mail.h"
39
40#include <stdlib.h>
41#include <string.h>
42
43mailmessage * mailmessage_new(void)
44{
45 mailmessage * msg_info;
46
47 msg_info = malloc(sizeof(* msg_info));
48 if (msg_info == NULL)
49 goto err;
50
51 msg_info->msg_driver = NULL;
52 msg_info->msg_session = NULL;
53 msg_info->msg_index = 0;
54 msg_info->msg_uid = NULL;
55
56 msg_info->msg_cached = FALSE;
57 msg_info->msg_size = 0;
58 msg_info->msg_fields = NULL;
59 memset(&msg_info->msg_single_fields,
60 0, sizeof(struct mailimf_single_fields));
61 msg_info->msg_resolved = FALSE;
62 msg_info->msg_flags = NULL;
63
64 msg_info->msg_mime = NULL;
65 msg_info->msg_data = NULL;
66
67 msg_info->msg_folder = NULL;
68 msg_info->msg_user_data = NULL;
69
70 return msg_info;
71
72 err:
73 return NULL;
74}
75
76void mailmessage_free(mailmessage * msg_info)
77{
78 if (msg_info->msg_driver != NULL) {
79 if (msg_info->msg_driver->msg_uninitialize != NULL)
80 msg_info->msg_driver->msg_uninitialize(msg_info);
81 }
82
83 if (msg_info->msg_fields != NULL)
84 mailimf_fields_free(msg_info->msg_fields);
85 if (msg_info->msg_mime != NULL)
86 mailmime_free(msg_info->msg_mime);
87 if (msg_info->msg_flags != NULL)
88 mail_flags_free(msg_info->msg_flags);
89 if (msg_info->msg_uid != NULL)
90 free(msg_info->msg_uid);
91 free(msg_info);
92}
diff --git a/kmicromail/libetpan/generic/mailmessage_types.h b/kmicromail/libetpan/generic/mailmessage_types.h
new file mode 100644
index 0000000..655ed2c
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailmessage_types.h
@@ -0,0 +1,50 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMESSAGE_TYPES_H
37
38#define MAILMESSAGE_TYPES_H
39
40#include <libetpan/maildriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46#ifdef __cplusplus
47}
48#endif
49
50#endif
diff --git a/kmicromail/libetpan/generic/mailstorage.c b/kmicromail/libetpan/generic/mailstorage.c
new file mode 100644
index 0000000..25e561e
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailstorage.c
@@ -0,0 +1,334 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailstorage.h"
37
38#include "maildriver.h"
39
40#include <stdlib.h>
41#include <string.h>
42
43static int mailstorage_get_folder(struct mailstorage * storage,
44 char * pathname, mailsession ** result);
45
46struct mailfolder * mailfolder_new(struct mailstorage * storage,
47 char * pathname, char * virtual_name)
48{
49 struct mailfolder * folder;
50
51 folder = malloc(sizeof(struct mailfolder));
52 if (folder == NULL)
53 goto err;
54
55 if (pathname != NULL) {
56 folder->fld_pathname = strdup(pathname);
57 if (folder->fld_pathname == NULL)
58 goto free;
59 }
60 else
61 folder->fld_pathname = NULL;
62
63 if (virtual_name != NULL) {
64 folder->fld_virtual_name = strdup(virtual_name);
65 if (folder->fld_virtual_name == NULL)
66 goto free_pathname;
67 }
68 else
69 folder->fld_virtual_name = NULL;
70
71 folder->fld_storage = storage;
72
73 folder->fld_session = NULL;
74 folder->fld_shared_session = 0;
75 folder->fld_pos = NULL;
76
77 folder->fld_parent = NULL;
78 folder->fld_sibling_index = 0;
79 folder->fld_children = carray_new(128);
80 if (folder->fld_children == NULL)
81 goto free_virtualname;
82
83 return folder;
84
85free_virtualname:
86 if (folder->fld_virtual_name != NULL)
87 free(folder->fld_virtual_name);
88free_pathname:
89 if (folder->fld_pathname != NULL)
90 free(folder->fld_pathname);
91free:
92 free(folder);
93err:
94 return NULL;
95}
96
97void mailfolder_free(struct mailfolder * folder)
98{
99 if (folder->fld_parent != NULL)
100 mailfolder_detach_parent(folder);
101
102 while (carray_count(folder->fld_children) > 0) {
103 struct mailfolder * child;
104
105 child = carray_get(folder->fld_children, 0);
106 mailfolder_detach_parent(child);
107 }
108
109 carray_free(folder->fld_children);
110
111 if (folder->fld_session != NULL)
112 mailfolder_disconnect(folder);
113
114 if (folder->fld_virtual_name != NULL)
115 free(folder->fld_virtual_name);
116 if (folder->fld_pathname != NULL)
117 free(folder->fld_pathname);
118 free(folder);
119}
120
121int mailfolder_connect(struct mailfolder * folder)
122{
123 mailsession * session;
124 int res;
125 int r;
126
127 if (folder->fld_storage == NULL) {
128 res = MAIL_ERROR_INVAL;
129 goto err;
130 }
131
132 if (folder->fld_storage->sto_session == NULL) {
133 r = mailstorage_connect(folder->fld_storage);
134 if (r != MAIL_NO_ERROR) {
135 res = r;
136 goto err;
137 }
138 }
139
140 if (folder->fld_session != NULL) {
141 if ((folder->fld_pathname != NULL) && (folder->fld_shared_session)) {
142 if (folder->fld_session->sess_driver->sess_select_folder != NULL) {
143 r = mailsession_select_folder(folder->fld_session,
144 folder->fld_pathname);
145 if (r != MAIL_NO_ERROR) {
146 res = r;
147 goto err;
148 }
149 }
150 }
151
152 return MAIL_NO_ERROR;
153 }
154
155 r = mailstorage_get_folder(folder->fld_storage, folder->fld_pathname,
156 &session);
157 if (r != MAIL_NO_ERROR) {
158 res = r;
159 goto err;
160 }
161 folder->fld_session = session;
162 folder->fld_shared_session = (session == folder->fld_storage->sto_session);
163 if (folder->fld_shared_session) {
164 r = clist_append(folder->fld_storage->sto_shared_folders, folder);
165 if (r < 0) {
166 folder->fld_session = NULL;
167 res = MAIL_ERROR_MEMORY;
168 goto err;
169 }
170 folder->fld_pos = clist_end(folder->fld_storage->sto_shared_folders);
171 }
172
173 return MAIL_NO_ERROR;
174
175err:
176 return res;
177}
178
179void mailfolder_disconnect(struct mailfolder * folder)
180{
181 if (folder->fld_session == NULL)
182 return;
183
184 if (folder->fld_shared_session) {
185 clist_delete(folder->fld_storage->sto_shared_folders, folder->fld_pos);
186 folder->fld_pos = NULL;
187 }
188 else {
189 mailsession_logout(folder->fld_session);
190 mailsession_free(folder->fld_session);
191 }
192
193 folder->fld_session = NULL;
194}
195
196int mailfolder_add_child(struct mailfolder * parent,
197 struct mailfolder * child)
198{
199 unsigned int index;
200 int r;
201
202 r = carray_add(parent->fld_children, child, &index);
203 if (r < 0)
204 return MAIL_ERROR_MEMORY;
205
206 child->fld_sibling_index = index;
207 child->fld_parent = parent;
208
209 return MAIL_NO_ERROR;
210}
211
212int mailfolder_detach_parent(struct mailfolder * folder)
213{
214 unsigned int i;
215 int r;
216
217 if (folder->fld_parent == NULL)
218 return MAIL_ERROR_INVAL;
219
220 r = carray_delete_slow(folder->fld_parent->fld_children,
221 folder->fld_sibling_index);
222 if (r < 0)
223 return MAIL_ERROR_INVAL;
224
225 for(i = 0 ; i < carray_count(folder->fld_parent->fld_children) ; i ++) {
226 struct mailfolder * child;
227
228 child = carray_get(folder->fld_parent->fld_children, i);
229 child->fld_sibling_index = i;
230 }
231
232 folder->fld_parent = NULL;
233 folder->fld_sibling_index = 0;
234
235 return MAIL_NO_ERROR;
236}
237
238struct mailstorage * mailstorage_new(char * sto_id)
239{
240 struct mailstorage * storage;
241
242 storage = malloc(sizeof(struct mailstorage));
243 if (storage == NULL)
244 goto err;
245
246 if (sto_id != NULL) {
247 storage->sto_id = strdup(sto_id);
248 if (storage->sto_id == NULL)
249 goto free;
250 }
251 else
252 storage->sto_id = NULL;
253
254 storage->sto_data = NULL;
255 storage->sto_session = NULL;
256 storage->sto_driver = NULL;
257 storage->sto_shared_folders = clist_new();
258 if (storage->sto_shared_folders == NULL)
259 goto free_id;
260
261 return storage;
262
263 free_id:
264 if (storage->sto_id != NULL)
265 free(storage->sto_id);
266 free:
267 free(storage);
268 err:
269 return NULL;
270}
271
272void mailstorage_free(struct mailstorage * storage)
273{
274 if (storage->sto_session != NULL)
275 mailstorage_disconnect(storage);
276
277 if (storage->sto_driver != NULL) {
278 if (storage->sto_driver->sto_uninitialize != NULL)
279 storage->sto_driver->sto_uninitialize(storage);
280 }
281
282 clist_free(storage->sto_shared_folders);
283
284 if (storage->sto_id != NULL)
285 free(storage->sto_id);
286
287 free(storage);
288}
289
290int mailstorage_connect(struct mailstorage * storage)
291{
292 if (storage->sto_session != NULL)
293 return MAIL_NO_ERROR;
294
295 if (!clist_isempty(storage->sto_shared_folders))
296 return MAIL_ERROR_BAD_STATE;
297
298 if (storage->sto_driver->sto_connect == NULL)
299 return MAIL_ERROR_NOT_IMPLEMENTED;
300
301 return storage->sto_driver->sto_connect(storage);
302}
303
304
305void mailstorage_disconnect(struct mailstorage * storage)
306{
307 int r;
308 clistiter * cur;
309
310 while ((cur = clist_begin(storage->sto_shared_folders)) != NULL) {
311 struct mailfolder * folder;
312
313 folder = cur->data;
314 mailfolder_disconnect(folder);
315 }
316
317 if (storage->sto_session == NULL)
318 return;
319
320 r = mailsession_logout(storage->sto_session);
321
322 mailsession_free(storage->sto_session);
323 storage->sto_session = NULL;
324}
325
326static int mailstorage_get_folder(struct mailstorage * storage,
327 char * pathname, mailsession ** result)
328{
329 if (storage->sto_driver->sto_get_folder_session == NULL)
330 return MAIL_ERROR_NOT_IMPLEMENTED;
331
332 return storage->sto_driver->sto_get_folder_session(storage,
333 pathname, result);
334}
diff --git a/kmicromail/libetpan/generic/mailstorage.h b/kmicromail/libetpan/generic/mailstorage.h
new file mode 100644
index 0000000..d56aef1
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailstorage.h
@@ -0,0 +1,98 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAIL_STORAGE_H
37
38#define MAIL_STORAGE_H
39
40#include <libetpan/maildriver_types.h>
41#include <libetpan/mailstorage_types.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47/* storage */
48
49/*
50 mailstorage_new
51
52 This function creates an empty storage. This storage have to be initialized.
53 The "driver" and "data" fields should be initialized.
54
55 @param id is the name of the storage. It can be NULL.
56 The given parameter is no more needed when the creation is finished.
57 The given string is duplicated.
58
59 @return The mail storage is returned.
60*/
61
62struct mailstorage * mailstorage_new(char * sto_id);
63
64void mailstorage_free(struct mailstorage * storage);
65
66/*
67 session will be initialized on success.
68*/
69
70int mailstorage_connect(struct mailstorage * storage);
71
72void mailstorage_disconnect(struct mailstorage * storage);
73
74
75/* folder */
76
77struct mailfolder * mailfolder_new(struct mailstorage * fld_storage,
78 char * fld_pathname, char * fld_virtual_name);
79
80void mailfolder_free(struct mailfolder * folder);
81
82int mailfolder_add_child(struct mailfolder * parent,
83 struct mailfolder * child);
84
85int mailfolder_detach_parent(struct mailfolder * folder);
86
87int mailfolder_connect(struct mailfolder * folder);
88
89void mailfolder_disconnect(struct mailfolder * folder);
90
91
92#ifdef __cplusplus
93}
94#endif
95
96#endif
97
98
diff --git a/kmicromail/libetpan/generic/mailstorage_tools.c b/kmicromail/libetpan/generic/mailstorage_tools.c
new file mode 100644
index 0000000..92e2657
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailstorage_tools.c
@@ -0,0 +1,372 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailstorage_tools.h"
37
38#include "libetpan-config.h"
39
40#include <sys/types.h>
41#include <netdb.h>
42#include <netinet/in.h>
43#include <sys/socket.h>
44#include <unistd.h>
45#include <stdlib.h>
46#include <sys/wait.h>
47#include <sys/ioctl.h>
48#include <fcntl.h>
49#include <string.h>
50
51#include "mail.h"
52#include "mailmessage.h"
53#include "maildriver.h"
54
55/* tools */
56
57/* connection to TCP/IP server */
58
59static int tcp_connect(char * server, uint16_t port)
60{
61 struct hostent * remotehost;
62 struct sockaddr_in sa;
63 int s;
64 int r;
65
66 s = socket(PF_INET, SOCK_STREAM, 0);
67 if (s == -1)
68 goto err;
69
70 remotehost = gethostbyname(server);
71 if (remotehost == NULL)
72 goto close_socket;
73
74 sa.sin_family = AF_INET;
75 sa.sin_port = htons(port);
76 memcpy(&sa.sin_addr, remotehost->h_addr, remotehost->h_length);
77
78 r = connect(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in));
79 if (r == -1)
80 goto close_socket;
81
82 return s;
83
84 close_socket:
85 close(s);
86 err:
87 return -1;
88}
89
90
91/* connection through a shell command */
92
93static void do_exec_command(int fd, const char *command,
94 char *servername, uint16_t port)
95{
96 int i, maxopen;
97
98 if (fork() > 0) {
99 /* Fork again to become a child of init rather than
100 the etpan client. */
101 exit(0);
102 }
103
104 if (servername)
105 setenv("ETPANSERVER", servername, 1);
106 else
107 unsetenv("ETPANSERVER");
108
109 if (port) {
110 char porttext[20];
111
112 snprintf(porttext, sizeof(porttext), "%d", port);
113 setenv("ETPANPORT", porttext, 1);
114 }
115 else {
116 unsetenv("ETPANPORT");
117 }
118
119 /* Not a lot we can do if there's an error other than bail. */
120 if (dup2(fd, 0) == -1)
121 exit(1);
122 if (dup2(fd, 1) == -1)
123 exit(1);
124
125 /* Should we close stderr and reopen /dev/null? */
126
127 maxopen = sysconf(_SC_OPEN_MAX);
128 for (i=3; i < maxopen; i++)
129 close(i);
130
131#ifdef TIOCNOTTY
132 /* Detach from the controlling tty if we have one. Otherwise,
133 SSH might do something stupid like trying to use it instead
134 of running $SSH_ASKPASS. Doh. */
135 fd = open("/dev/tty", O_RDONLY);
136 if (fd != -1) {
137 ioctl(fd, TIOCNOTTY, NULL);
138 close(fd);
139 }
140#endif /* TIOCNOTTY */
141
142 execl("/bin/sh", "/bin/sh", "-c", command, NULL);
143
144 /* Eep. Shouldn't reach this */
145 exit(1);
146}
147
148static int subcommand_connect(char *command, char *servername, uint16_t port)
149{
150 int sockfds[2];
151 pid_t childpid;
152
153 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds))
154 return -1;
155
156 childpid = fork();
157 if (!childpid) {
158 do_exec_command(sockfds[1], command, servername, port);
159 }
160 else if (childpid == -1) {
161 close(sockfds[0]);
162 close(sockfds[1]);
163 return -1;
164 }
165
166 close(sockfds[1]);
167
168 /* Reap child, leaving grandchild process to run */
169 waitpid(childpid, NULL, 0);
170
171 return sockfds[0];
172}
173
174int mailstorage_generic_connect(mailsession_driver * driver,
175 char * servername,
176 uint16_t port,
177 char * command,
178 int connection_type,
179 int cache_function_id,
180 char * cache_directory,
181 int flags_function_id,
182 char * flags_directory,
183 mailsession ** result)
184{
185 int r;
186 int res;
187 mailstream * stream;
188 int fd;
189 mailsession * session;
190 int connect_result;
191
192 switch (connection_type) {
193 case CONNECTION_TYPE_PLAIN:
194 case CONNECTION_TYPE_TRY_STARTTLS:
195 case CONNECTION_TYPE_STARTTLS:
196 case CONNECTION_TYPE_TLS:
197 fd = tcp_connect(servername, port);
198 if (fd == -1) {
199 res = MAIL_ERROR_CONNECT;
200 goto err;
201 }
202 break;
203
204 case CONNECTION_TYPE_COMMAND:
205 case CONNECTION_TYPE_COMMAND_TRY_STARTTLS:
206 case CONNECTION_TYPE_COMMAND_STARTTLS:
207 case CONNECTION_TYPE_COMMAND_TLS:
208 fd = subcommand_connect(command, servername, port);
209 break;
210
211 default:
212 fd = -1;
213 break;
214 }
215
216 if (fd == -1) {
217 res = MAIL_ERROR_INVAL;
218 goto err;
219 }
220
221 switch (connection_type) {
222 case CONNECTION_TYPE_PLAIN:
223 case CONNECTION_TYPE_TRY_STARTTLS:
224 case CONNECTION_TYPE_STARTTLS:
225 case CONNECTION_TYPE_COMMAND:
226 case CONNECTION_TYPE_COMMAND_TRY_STARTTLS:
227 case CONNECTION_TYPE_COMMAND_STARTTLS:
228 stream = mailstream_socket_open(fd);
229 break;
230
231 case CONNECTION_TYPE_TLS:
232 case CONNECTION_TYPE_COMMAND_TLS:
233 stream = mailstream_ssl_open(fd);
234 break;
235
236 default:
237 stream = NULL;
238 break;
239 }
240
241 if (stream == NULL) {
242 res = MAIL_ERROR_STREAM;
243 close(fd);
244 goto err;
245 }
246
247 session = mailsession_new(driver);
248 if (session == NULL) {
249 res = MAIL_ERROR_MEMORY;
250 goto close_stream;
251 }
252
253 if (cache_directory != NULL) {
254 char cache_directory_server[PATH_MAX];
255
256 snprintf(cache_directory_server, PATH_MAX, "%s/%s",
257 cache_directory, servername);
258
259 r = mailsession_parameters(session,
260 cache_function_id,
261 cache_directory_server);
262 if (r != MAIL_NO_ERROR) {
263 res = r;
264 goto close_stream;
265 }
266 }
267
268 if (flags_directory != NULL) {
269 char flags_directory_server[PATH_MAX];
270
271 snprintf(flags_directory_server, PATH_MAX, "%s/%s",
272 flags_directory, servername);
273
274 r = mailsession_parameters(session,
275 flags_function_id,
276 flags_directory_server);
277 if (r != MAIL_NO_ERROR) {
278 res = r;
279 goto close_stream;
280 }
281 }
282
283 r = mailsession_connect_stream(session, stream);
284 switch (r) {
285 case MAIL_NO_ERROR_NON_AUTHENTICATED:
286 case MAIL_NO_ERROR_AUTHENTICATED:
287 case MAIL_NO_ERROR:
288 break;
289 default:
290 res = r;
291 goto free;
292 }
293
294 connect_result = r;
295
296 switch (connection_type) {
297 case CONNECTION_TYPE_TRY_STARTTLS:
298 case CONNECTION_TYPE_COMMAND_TRY_STARTTLS:
299 r = mailsession_starttls(session);
300 if ((r != MAIL_NO_ERROR) && (r != MAIL_ERROR_NO_TLS)) {
301 res = r;
302 goto free;
303 }
304 break;
305
306 case CONNECTION_TYPE_STARTTLS:
307 case CONNECTION_TYPE_COMMAND_STARTTLS:
308 r = mailsession_starttls(session);
309 if (r != MAIL_NO_ERROR) {
310 res = r;
311 goto free;
312 }
313 }
314
315 * result = session;
316
317 return connect_result;
318
319 close_stream:
320 mailstream_close(stream);
321 free:
322 mailsession_free(session);
323 err:
324 return res;
325}
326
327
328
329
330
331int mailstorage_generic_auth(mailsession * session,
332 int connect_result,
333 int auth_type,
334 char * login,
335 char * password)
336{
337 int must_auth;
338 int r;
339 int res;
340
341 r = connect_result;
342
343 must_auth = FALSE;
344 switch (r) {
345 case MAIL_NO_ERROR_NON_AUTHENTICATED:
346 must_auth = TRUE;
347 break;
348 case MAIL_NO_ERROR_AUTHENTICATED:
349 case MAIL_NO_ERROR:
350 break;
351 default:
352 res = r;
353 goto err;
354 }
355
356 if ((login == NULL) || (password == NULL))
357 must_auth = FALSE;
358
359 if (must_auth) {
360 r = mailsession_login(session, login, password);
361 if (r != MAIL_NO_ERROR) {
362 mailsession_logout(session);
363 res = r;
364 goto err;
365 }
366 }
367
368 return MAIL_NO_ERROR;
369
370 err:
371 return res;
372}
diff --git a/kmicromail/libetpan/generic/mailstorage_tools.h b/kmicromail/libetpan/generic/mailstorage_tools.h
new file mode 100644
index 0000000..280b214
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailstorage_tools.h
@@ -0,0 +1,67 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailstorage.h"
37
38#ifndef MAILSTORAGE_TOOLS_H
39
40#define MAILSTORAGE_TOOLS_H
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46int mailstorage_generic_connect(mailsession_driver * driver,
47 char * servername,
48 uint16_t port,
49 char * command,
50 int connection_type,
51 int cache_function_id,
52 char * cache_directory,
53 int flags_function_id,
54 char * flags_directory,
55 mailsession ** result);
56
57int mailstorage_generic_auth(mailsession * session,
58 int connect_result,
59 int auth_type,
60 char * login,
61 char * password);
62
63#ifdef __cplusplus
64}
65#endif
66
67#endif
diff --git a/kmicromail/libetpan/generic/mailstorage_types.h b/kmicromail/libetpan/generic/mailstorage_types.h
new file mode 100644
index 0000000..5e08f80
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailstorage_types.h
@@ -0,0 +1,203 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSTORAGE_TYPES_H
37
38#define MAILSTORAGE_TYPES_H
39
40#include <libetpan/maildriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46struct mailstorage;
47
48typedef struct mailstorage_driver mailstorage_driver;
49
50
51/*
52 There is three kinds of identities :
53 - storage
54 - folders
55 - session
56
57 A storage (struct mailstorage) represents whether a server or
58 a main path,
59
60 A storage can be an IMAP server, the root path of a MH or a mbox file.
61
62 Folders (struct mailfolder) are the mailboxes we can
63 choose in the server or as sub-folder of the main path.
64
65 Folders for IMAP are the IMAP mailboxes, for MH this is one of the
66 folder of the MH storage, for mbox, there is only one folder, the
67 mbox file content;
68
69 A mail session (struct mailsession) is whether a connection to a server
70 or a path that is open. It is the abstraction lower folders and storage.
71 It allow us to send commands.
72
73 We have a session driver for mail session for each kind of storage.
74
75 From a session, we can get a message (struct mailmessage) to read.
76 We have a message driver for each kind of storage.
77*/
78
79/*
80 mailstorage_driver is the driver structure for mail storages
81
82 - name is the name of the driver
83
84 - connect() connects the storage to the remote access or to
85 the path in the local filesystem.
86
87 - get_folder() can have two kinds of behaviour.
88 Either it creates a new session and independant from the session
89 used by the storage and select the given mailbox or
90 it selects the given mailbox in the current session.
91 It depends on the efficiency of the mail driver.
92
93 - uninitialize() frees the data created with mailstorage constructor.
94*/
95
96struct mailstorage_driver {
97 char * sto_name;
98 int (* sto_connect)(struct mailstorage * storage);
99 int (* sto_get_folder_session)(struct mailstorage * storage,
100 char * pathname, mailsession ** result);
101 void (* sto_uninitialize)(struct mailstorage * storage);
102};
103
104/*
105 mailstorage is the data structure for a storage
106
107 - id is the name of the storage, it can be NULL.
108
109 - data is the data specific to the driver.
110 This is the internal state of the storage.
111
112 - session is the session related to the storage.
113
114 - driver is the driver for the storage.
115
116 - shared_folders is the list of folders returned by the storage.
117*/
118
119struct mailstorage {
120 char * sto_id;
121 void * sto_data;
122 mailsession * sto_session;
123 mailstorage_driver * sto_driver;
124 clist * sto_shared_folders; /* list of (struct mailfolder *) */
125
126 void * sto_user_data;
127};
128
129
130
131/*
132 mailfolder is the data structure for a mailbox
133
134 - pathname is the path of the mailbox on the storage
135
136 - virtual_name is the folder identifier, it can be a path,
137 a name or NULL.
138
139 - storage is the storage to which the folder belongs to.
140
141 - session is the session related to the folder. It can be
142 different of the session of the storage.
143
144 - shared_session is != 0 if the session is the same as the
145 session of the storage.
146
147 - pos is the position of the folder in the "shared_folders" field
148 of the storage.
149
150 folders can be chained into a tree.
151
152 - parent is the parent of the folder.
153
154 - sibling_index is the index of the folder in the list of children
155 of the parent.
156
157 - children is the folder.
158*/
159
160struct mailfolder {
161 char * fld_pathname;
162 char * fld_virtual_name;
163
164 struct mailstorage * fld_storage;
165
166 mailsession * fld_session;
167 int fld_shared_session;
168 clistiter * fld_pos;
169
170 struct mailfolder * fld_parent;
171 unsigned int fld_sibling_index;
172 carray * fld_children; /* array of (struct mailfolder *) */
173
174 void * fld_user_data;
175};
176
177/*
178 this is the type of socket connection
179*/
180
181enum {
182 CONNECTION_TYPE_PLAIN, /* when the connection is plain text */
183 CONNECTION_TYPE_STARTTLS, /* when the connection is first plain,
184 then, we want to switch to
185 TLS (secure connection) */
186 CONNECTION_TYPE_TRY_STARTTLS, /* the connection is first plain,
187 then, we will try to switch to TLS */
188 CONNECTION_TYPE_TLS, /* the connection is over TLS */
189 CONNECTION_TYPE_COMMAND, /* the connection is over a shell command */
190 CONNECTION_TYPE_COMMAND_STARTTLS, /* the connection is over a shell
191 command and STARTTLS will be used */
192 CONNECTION_TYPE_COMMAND_TRY_STARTTLS, /* the connection is over
193 a shell command and STARTTLS will
194 be tried */
195 CONNECTION_TYPE_COMMAND_TLS, /* the connection is over a shell
196 command in TLS */
197};
198
199#ifdef __cplusplus
200}
201#endif
202
203#endif
diff --git a/kmicromail/libetpan/generic/mailthread.c b/kmicromail/libetpan/generic/mailthread.c
new file mode 100644
index 0000000..1dca70d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailthread.c
@@ -0,0 +1,1631 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailthread.h"
37#include "mailthread_types.h"
38
39#include <string.h>
40#include <time.h>
41#include <stdlib.h>
42#include <ctype.h>
43
44#include "mail.h"
45#include "chash.h"
46#include "carray.h"
47#include "clist.h"
48#include "mailmessage.h"
49
50static inline char * get_msg_id(mailmessage * msg)
51{
52 if (msg->msg_single_fields.fld_message_id != NULL)
53 return msg->msg_single_fields.fld_message_id->mid_value;
54 else
55 return NULL;
56}
57
58static inline clist * get_ref(mailmessage * msg)
59{
60 if (msg->msg_single_fields.fld_references != NULL)
61 return msg->msg_single_fields.fld_references->mid_list;
62 else
63 return NULL;
64}
65
66static inline clist * get_in_reply_to(mailmessage * msg)
67{
68 if (msg->msg_single_fields.fld_in_reply_to != NULL)
69 return msg->msg_single_fields.fld_in_reply_to->mid_list;
70 else
71 return NULL;
72}
73
74static inline int skip_subj_blob(char * subj, size_t * begin,
75 size_t length)
76{
77 /* subj-blob = "[" *BLOBCHAR "]" *WSP */
78 size_t cur_token;
79
80 cur_token = * begin;
81
82 if (subj[cur_token] != '[')
83 return FALSE;
84
85 cur_token ++;
86
87 while (1) {
88 if (cur_token >= length)
89 return FALSE;
90
91 if (subj[cur_token] == '[')
92 return FALSE;
93
94 if (subj[cur_token] == ']')
95 break;
96
97 cur_token ++;
98 }
99
100 cur_token ++;
101
102 while (1) {
103 if (cur_token >= length)
104 break;
105
106 if (subj[cur_token] != ' ')
107 break;
108
109 cur_token ++;
110 }
111
112 * begin = cur_token;
113
114 return TRUE;
115}
116
117static inline int skip_subj_refwd(char * subj, size_t * begin,
118 size_t length)
119{
120 /* subj-refwd = ("re" / ("fw" ["d"])) *WSP [subj-blob] ":" */
121 size_t cur_token;
122 int prefix;
123
124 cur_token = * begin;
125
126 prefix = FALSE;
127 if (length >= 3) {
128 if (strncasecmp(subj + cur_token, "fwd", 3) == 0) {
129 cur_token += 3;
130 prefix = TRUE;
131 }
132 }
133 if (!prefix) {
134 if (length >= 2) {
135 if (strncasecmp(subj + cur_token, "fw", 2) == 0) {
136 cur_token += 2;
137 prefix = TRUE;
138 }
139 else if (strncasecmp(subj + cur_token, "re", 2) == 0) {
140 cur_token += 2;
141 prefix = TRUE;
142 }
143 }
144 }
145
146 if (!prefix)
147 return FALSE;
148
149 while (1) {
150 if (cur_token >= length)
151 break;
152
153 if (subj[cur_token] != ' ')
154 break;
155
156 cur_token ++;
157 }
158
159 skip_subj_blob(subj, &cur_token, length);
160
161 if (subj[cur_token] != ':')
162 return FALSE;
163
164 cur_token ++;
165
166 * begin = cur_token;
167
168 return TRUE;
169}
170
171static inline int skip_subj_leader(struct mailmessage_tree * tree,
172 char * subj, size_t * begin,
173 size_t length)
174{
175 size_t cur_token;
176
177 cur_token = * begin;
178
179 /* subj-leader = (*subj-blob subj-refwd) / WSP */
180
181 if (subj[cur_token] == ' ') {
182 cur_token ++;
183 }
184 else {
185 while (cur_token < length) {
186 if (!skip_subj_blob(subj, &cur_token, length))
187 break;
188 }
189 if (!skip_subj_refwd(subj, &cur_token, length))
190 return FALSE;
191 tree->node_is_reply = TRUE;
192 }
193
194 * begin = cur_token;
195
196 return TRUE;
197}
198
199
200static char * extract_subject(char * default_from,
201 struct mailmessage_tree * tree,
202 char * str)
203{
204 char * subj;
205 char * cur;
206 char * write_pos;
207 size_t len;
208 size_t begin;
209
210 char * decoded;
211 size_t cur_token;
212
213 int do_repeat_5;
214 int do_repeat_6;
215 int r;
216
217 /*
218 (1) Convert any RFC 2047 encoded-words in the subject to
219 UTF-8.
220 */
221
222 decoded = NULL;
223
224 cur_token = 0;
225 r = mailmime_encoded_phrase_parse(default_from, str, strlen(str),
226 &cur_token, "utf-8",
227 &decoded);
228
229 if (r == MAILIMF_NO_ERROR) {
230 subj = decoded;
231 }
232 else
233 subj = strdup(str);
234
235 len = strlen(subj);
236
237 /*
238 Convert all tabs and continuations to space.
239 Convert all multiple spaces to a single space.
240 */
241
242 cur = subj;
243 write_pos = subj;
244 while (* cur != '\0') {
245 int cont;
246
247 switch (* cur) {
248 case '\t':
249 case '\r':
250 case '\n':
251 cont = TRUE;
252
253 cur ++;
254 while (* cur && cont) {
255 switch (* cur) {
256 case '\t':
257 case '\r':
258 case '\n':
259 cont = TRUE;
260 break;
261 default:
262 cont = FALSE;
263 break;
264 }
265 cur ++;
266 }
267
268 * write_pos = ' ';
269 write_pos ++;
270
271 break;
272
273 default:
274 * write_pos = * cur;
275 write_pos ++;
276
277 cur ++;
278
279 break;
280 }
281 }
282 * write_pos = '\0';
283
284 begin = 0;
285
286 do {
287 do_repeat_6 = FALSE;
288
289 /*
290 (2) Remove all trailing text of the subject that matches
291 the subj-trailer ABNF, repeat until no more matches are
292 possible.
293 */
294
295 while (len > 0) {
296 int chg;
297
298 chg = FALSE;
299
300 /* subj-trailer = "(fwd)" / WSP */
301 if (subj[len - 1] == ' ') {
302 subj[len - 1] = '\0';
303 len --;
304 }
305 else {
306 if (len < 5)
307 break;
308
309 if (strncasecmp(subj + len - 5, "(fwd)", 5) != 0)
310 break;
311
312 subj[len - 5] = '\0';
313 len -= 5;
314 tree->node_is_reply = TRUE;
315 }
316 }
317
318 do {
319 size_t saved_begin;
320
321 do_repeat_5 = FALSE;
322
323 /*
324 (3) Remove all prefix text of the subject that matches the
325 subj-leader ABNF.
326 */
327
328 if (skip_subj_leader(tree, subj, &begin, len))
329 do_repeat_5 = TRUE;
330
331 /*
332 (4) If there is prefix text of the subject that matches the
333 subj-blob ABNF, and removing that prefix leaves a non-empty
334 subj-base, then remove the prefix text.
335 */
336
337 saved_begin = begin;
338 if (skip_subj_blob(subj, &begin, len)) {
339 if (begin == len) {
340 /* this will leave a empty subject base */
341 begin = saved_begin;
342 }
343 else
344 do_repeat_5 = TRUE;
345 }
346
347 /*
348 (5) Repeat (3) and (4) until no matches remain.
349 Note: it is possible to defer step (2) until step (6),
350 but this requires checking for subj-trailer in step (4).
351 */
352
353 }
354 while (do_repeat_5);
355
356 /*
357 (6) If the resulting text begins with the subj-fwd-hdr ABNF
358 and ends with the subj-fwd-trl ABNF, remove the
359 subj-fwd-hdr and subj-fwd-trl and repeat from step (2).
360 */
361
362 if (len >= 5) {
363 size_t saved_begin;
364
365 saved_begin = begin;
366 if (strncasecmp(subj + begin, "[fwd:", 5) == 0) {
367 begin += 5;
368
369 if (subj[len - 1] != ']')
370 saved_begin = begin;
371 else {
372 tree->node_is_reply = TRUE;
373
374 subj[len - 1] = '\0';
375 len --;
376 do_repeat_6 = TRUE;
377 }
378 }
379 }
380
381 }
382 while (do_repeat_6);
383
384 /*
385 (7) The resulting text is the "base subject" used in
386 threading.
387 */
388
389 /* convert to upper case */
390
391 cur = subj + begin;
392 write_pos = subj;
393
394 while (* cur != '\0') {
395 * write_pos = (char) toupper((unsigned char) * cur);
396 cur ++;
397 write_pos ++;
398 }
399 * write_pos = '\0';
400
401 return subj;
402}
403
404static int get_extracted_subject(char * default_from,
405 struct mailmessage_tree * tree,
406 char ** result)
407{
408 if (tree->node_msg->msg_single_fields.fld_subject != NULL) {
409 char * subj;
410
411 subj = extract_subject(default_from,
412 tree, tree->node_msg->msg_single_fields.fld_subject->sbj_value);
413 if (subj == NULL)
414 return MAIL_ERROR_MEMORY;
415
416 * result = subj;
417
418 return MAIL_NO_ERROR;
419 }
420
421 return MAIL_ERROR_SUBJECT_NOT_FOUND;
422}
423
424static int get_thread_subject(char * default_from,
425 struct mailmessage_tree * tree,
426 char ** result)
427{
428 char * thread_subject;
429 int r;
430 unsigned int i;
431
432 if (tree->node_msg != NULL) {
433 if (tree->node_msg->msg_fields != NULL) {
434 r = get_extracted_subject(default_from, tree, &thread_subject);
435
436 if (r != MAIL_NO_ERROR)
437 return r;
438
439 * result = thread_subject;
440 return MAIL_NO_ERROR;
441 }
442 }
443
444 for(i = 0 ; i < carray_count(tree->node_children) ; i ++) {
445 struct mailmessage_tree * child;
446
447 child = carray_get(tree->node_children, i);
448
449 r = get_thread_subject(default_from, child, &thread_subject);
450
451 switch (r) {
452 case MAIL_NO_ERROR:
453 * result = thread_subject;
454 return MAIL_NO_ERROR;
455
456 case MAIL_ERROR_SUBJECT_NOT_FOUND:
457 /* do nothing */
458 break;
459
460 default:
461 return r;
462 }
463 }
464
465 return MAIL_ERROR_SUBJECT_NOT_FOUND;
466}
467
468
469
470#ifndef WRONG
471 #define WRONG(-1)
472#endif /* !defined WRONG */
473
474static int tmcomp(struct tm * atmp, struct tm * btmp)
475{
476 register intresult;
477
478 if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
479 (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
480 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
481 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
482 (result = (atmp->tm_min - btmp->tm_min)) == 0)
483 result = atmp->tm_sec - btmp->tm_sec;
484 return result;
485}
486
487static time_t mkgmtime(struct tm * tmp)
488{
489 register int dir;
490 register int bits;
491 register int saved_seconds;
492 time_t t;
493 struct tm yourtm, *mytm;
494
495 yourtm = *tmp;
496 saved_seconds = yourtm.tm_sec;
497 yourtm.tm_sec = 0;
498 /*
499 ** Calculate the number of magnitude bits in a time_t
500 ** (this works regardless of whether time_t is
501 ** signed or unsigned, though lint complains if unsigned).
502 */
503 for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
504 ;
505 /*
506 ** If time_t is signed, then 0 is the median value,
507 ** if time_t is unsigned, then 1 << bits is median.
508 */
509 t = (t < 0) ? 0 : ((time_t) 1 << bits);
510 for ( ; ; ) {
511 mytm = gmtime(&t);
512 dir = tmcomp(mytm, &yourtm);
513 if (dir != 0) {
514 if (bits-- < 0)
515 return WRONG;
516 if (bits < 0)
517 --t;
518 else if (dir > 0)
519 t -= (time_t) 1 << bits;
520 elset += (time_t) 1 << bits;
521 continue;
522 }
523 break;
524 }
525 t += saved_seconds;
526 return t;
527}
528
529static inline time_t get_date(mailmessage * msg)
530{
531 struct tm tmval;
532 time_t timeval;
533 struct mailimf_date_time * date_time;
534
535 if (msg->msg_single_fields.fld_orig_date == NULL)
536 return (time_t) -1;
537
538 date_time = msg->msg_single_fields.fld_orig_date->dt_date_time;
539
540 tmval.tm_sec = date_time->dt_sec;
541 tmval.tm_min = date_time->dt_min;
542 tmval.tm_hour = date_time->dt_hour;
543 tmval.tm_sec = date_time->dt_sec;
544 tmval.tm_mday = date_time->dt_day;
545 tmval.tm_mon = date_time->dt_month - 1;
546 tmval.tm_year = date_time->dt_year - 1900;
547
548 timeval = mkgmtime(&tmval);
549
550 timeval -= date_time->dt_zone * 36;
551
552 return timeval;
553}
554
555static inline int is_descendant(struct mailmessage_tree * node,
556 struct mailmessage_tree * maybe_child)
557{
558 unsigned int i;
559
560 for(i = 0 ; i < carray_count(node->node_children) ; i++) {
561 struct mailmessage_tree * tree;
562
563 tree = carray_get(node->node_children, i);
564 if (tree == maybe_child)
565 return TRUE;
566 if (carray_count(tree->node_children) != 0)
567 if (is_descendant(tree, maybe_child))
568 return TRUE;
569 }
570
571 return FALSE;
572}
573
574static int delete_dummy(carray * rootlist, carray * sibling_list,
575 unsigned int cur, unsigned int * pnext)
576{
577 struct mailmessage_tree * env_tree;
578 int res;
579 int r;
580 unsigned int cur_child;
581 unsigned int next;
582
583 env_tree = carray_get(sibling_list, cur);
584
585 cur_child = 0;
586 while (cur_child < carray_count(env_tree->node_children)) {
587 delete_dummy(rootlist, env_tree->node_children, cur_child, &cur_child);
588 }
589
590 if (env_tree->node_msg == NULL) {
591 if (carray_count(env_tree->node_children) == 0) {
592
593 /* If it is a dummy message with NO children, delete it. */
594 mailmessage_tree_free(env_tree);
595 carray_delete(sibling_list, cur);
596 next = cur;
597 }
598 else {
599 /* If it is a dummy message with children, delete it, but
600 promote its children to the current level. */
601
602 /*
603 Do not promote the children if doing so would make them
604 children of the root, unless there is only one child.
605 */
606
607 cur_child = 0;
608 if ((sibling_list != rootlist) ||
609 (carray_count(env_tree->node_children) == 1)) {
610 while (cur_child < carray_count(env_tree->node_children)) {
611 struct mailmessage_tree * child;
612
613 child = carray_get(env_tree->node_children, cur_child);
614 r = carray_add(sibling_list, child, NULL);
615 if (r < 0) {
616 res = MAIL_ERROR_MEMORY;
617 goto err;
618 }
619 /* set new parent of the children */
620 child->node_parent = env_tree->node_parent;
621
622 carray_delete(env_tree->node_children, cur_child);
623 }
624 mailmessage_tree_free(env_tree);
625 carray_delete(sibling_list, cur);
626 next = cur;
627 }
628 else
629 next = cur + 1;
630 }
631 }
632 else
633 next = cur + 1;
634
635 * pnext = next;
636
637 return MAIL_NO_ERROR;
638
639 err:
640 return res;
641}
642
643static inline time_t tree_get_date(struct mailmessage_tree * tree)
644{
645 if (tree->node_msg != NULL) {
646 return tree->node_date;
647 }
648 else {
649 struct mailmessage_tree * subtree;
650
651 if (carray_count(tree->node_children) == 0)
652 return (time_t) -1;
653
654 subtree = carray_get(tree->node_children, 0);
655
656 return subtree->node_date;
657 }
658}
659
660static inline uint32_t tree_get_index(struct mailmessage_tree * tree)
661{
662 if (tree->node_msg == NULL)
663 return 0;
664
665 return tree->node_msg->msg_index;
666}
667
668int mailthread_tree_timecomp(struct mailmessage_tree ** ptree1,
669 struct mailmessage_tree ** ptree2)
670{
671 time_t date1;
672 time_t date2;
673
674 date1 = tree_get_date(* ptree1);
675 date2 = tree_get_date(* ptree2);
676
677 if ((date1 == (time_t) -1) || (date2 == (time_t) -1)) {
678 uint32_t index1;
679 uint32_t index2;
680
681 index1 = tree_get_index(* ptree1);
682 index2 = tree_get_index(* ptree2);
683 return (int) ((long) index1 - (long) index2);
684 }
685
686 return (int) ((long) date1 - (long) date2);
687}
688
689static int tree_subj_time_comp(struct mailmessage_tree ** ptree1,
690 struct mailmessage_tree ** ptree2)
691{
692 char * subj1;
693 char * subj2;
694 time_t date1;
695 time_t date2;
696 int r;
697
698 subj1 = (* ptree1)->node_base_subject;
699 subj2 = (* ptree2)->node_base_subject;
700
701 if ((subj1 != NULL) && (subj2 != NULL))
702 r = strcmp(subj1, subj2);
703 else {
704 if ((subj1 == NULL) && (subj2 == NULL))
705 r = 0;
706 else if (subj1 == NULL)
707 r = -1;
708 else /* subj2 == NULL */
709 r = 1;
710 }
711
712 if (r != 0)
713 return r;
714
715 date1 = (* ptree1)->node_date;
716 date2 = (* ptree2)->node_date;
717
718 if ((date1 == (time_t) -1) || (date2 == (time_t) -1))
719 return ((int32_t) (* ptree1)->node_msg->msg_index) -
720 ((int32_t) (* ptree2)->node_msg->msg_index);
721
722 return (int) ((long) date1 - (long) date2);
723}
724
725
726
727int mail_thread_sort(struct mailmessage_tree * tree,
728 int (* comp_func)(struct mailmessage_tree **,
729 struct mailmessage_tree **),
730 int sort_sub)
731{
732 unsigned int cur;
733 int r;
734 int res;
735
736 for(cur = 0 ; cur < carray_count(tree->node_children) ; cur ++) {
737 struct mailmessage_tree * subtree;
738
739 subtree = carray_get(tree->node_children, cur);
740
741 if (sort_sub) {
742 r = mail_thread_sort(subtree, comp_func, sort_sub);
743 if (r != MAIL_NO_ERROR) {
744 res = r;
745 goto err;
746 }
747 }
748 }
749
750 qsort(carray_data(tree->node_children), carray_count(tree->node_children),
751 sizeof(struct mailmessage_tree *),
752 (int (*)(const void *, const void *)) comp_func);
753
754 return MAIL_NO_ERROR;
755
756 err:
757 return res;
758}
759
760
761static int
762mail_build_thread_references(char * default_from,
763 struct mailmessage_list * env_list,
764 struct mailmessage_tree ** result,
765 int use_subject,
766 int (* comp_func)(struct mailmessage_tree **,
767 struct mailmessage_tree **))
768{
769 int r;
770 int res;
771 chash * msg_id_hash;
772 unsigned int cur;
773 struct mailmessage_tree * root;
774 carray * rootlist;
775 carray * msg_list;
776 unsigned int i;
777 chash * subject_hash;
778
779 msg_id_hash = chash_new(128, CHASH_COPYNONE);
780 if (msg_id_hash == NULL) {
781 res = MAIL_ERROR_MEMORY;
782 goto err;
783 }
784
785 root = mailmessage_tree_new(NULL, (time_t) -1, NULL);
786 if (root == NULL) {
787 res = MAIL_ERROR_MEMORY;
788 goto free_hash;
789 }
790 rootlist = root->node_children;
791
792 msg_list = carray_new(128);
793 if (msg_list == NULL) {
794 res = MAIL_ERROR_MEMORY;
795 goto free_root;
796 }
797
798 /* collect message-ID */
799 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
800 mailmessage * msg;
801 char * msgid;
802 struct mailmessage_tree * env_tree;
803 chashdatum hashkey;
804 chashdatum hashdata;
805 chashdatum hashold;
806 time_t date;
807
808 msg = carray_get(env_list->msg_tab, i);
809
810 if (msg == NULL)
811 continue;
812
813 if (msg->msg_fields != NULL) {
814 msgid = get_msg_id(msg);
815
816 if (msgid == NULL) {
817 msgid = mailimf_get_message_id();
818 }
819 else {
820 hashkey.data = msgid;
821 hashkey.len = strlen(msgid);
822
823 if (chash_get(msg_id_hash, &hashkey, &hashdata) == 0)
824 msgid = mailimf_get_message_id();
825 else
826 msgid = strdup(msgid);
827 }
828
829 if (msgid == NULL) {
830 res = MAIL_ERROR_MEMORY;
831 goto free_list;
832 }
833
834 date = get_date(msg);
835
836 env_tree = mailmessage_tree_new(msgid, date, msg);
837 if (env_tree == NULL) {
838 res = MAIL_ERROR_MEMORY;
839 goto free_list;
840 }
841
842 r = carray_add(msg_list, env_tree, NULL);
843 if (r < 0) {
844 mailmessage_tree_free(env_tree);
845 res = MAIL_ERROR_MEMORY;
846 goto free_list;
847 }
848
849 hashkey.data = msgid;
850 hashkey.len = strlen(msgid);
851
852 hashdata.data = env_tree;
853 hashdata.len = 0;
854
855 r = chash_set(msg_id_hash, &hashkey, &hashdata, &hashold);
856 if (r < 0) {
857 res = MAIL_ERROR_MEMORY;
858 goto free_list;
859 }
860 }
861 }
862
863 /* (1) for all messages */
864
865 for(cur = 0 ; cur < carray_count(msg_list) ; cur ++) {
866 struct mailmessage_tree * env_tree;
867 mailmessage * msg;
868 clist * ref;
869
870 env_tree = carray_get(msg_list, cur);
871
872 msg = env_tree->node_msg;
873
874 ref = NULL;
875 if (msg != NULL) {
876 ref = get_ref(msg);
877 if (ref == NULL)
878 ref = get_in_reply_to(msg);
879 }
880
881 /* (A) Using the Message IDs in the message's references, link
882 the corresponding messages (those whose Message-ID header
883 line contains the given reference Message ID) together as
884 parent/child.
885 */
886
887 if (ref != NULL) {
888 /* try to start a tree */
889
890 clistiter * cur_ref;
891 chashdatum hashkey;
892 chashdatum hashdata;
893 chashdatum hashold;
894 struct mailmessage_tree * env_cur_tree;
895 struct mailmessage_tree * last_env_cur_tree;
896
897 env_cur_tree = NULL;
898 for(cur_ref = clist_begin(ref) ; cur_ref != NULL ;
899 cur_ref = clist_next(cur_ref)) {
900 char * msgid;
901
902 last_env_cur_tree = env_cur_tree;
903
904 msgid = clist_content(cur_ref);
905
906 hashkey.data = msgid;
907 hashkey.len = strlen(msgid);
908
909 r = chash_get(msg_id_hash, &hashkey, &hashdata);
910 if (r < 0) {
911 /* not found, create a dummy message */
912 msgid = strdup(msgid);
913 if (msgid == NULL) {
914 res = MAIL_ERROR_MEMORY;
915 goto free_list;
916 }
917
918 env_cur_tree = mailmessage_tree_new(msgid, (time_t) -1, NULL);
919 if (env_cur_tree == NULL) {
920 free(msgid);
921 res = MAIL_ERROR_MEMORY;
922 goto free_list;
923 }
924
925 r = carray_add(msg_list, env_cur_tree, NULL);
926 if (r < 0) {
927 mailmessage_tree_free(env_cur_tree);
928 res = MAIL_ERROR_MEMORY;
929 goto free_list;
930 }
931
932 hashkey.data = msgid;
933 hashkey.len = strlen(msgid);
934
935 hashdata.data = env_cur_tree;
936 hashdata.len = 0;
937
938 r = chash_set(msg_id_hash, &hashkey, &hashdata, &hashold);
939 if (r < 0) {
940 res = MAIL_ERROR_MEMORY;
941 goto free_list;
942 }
943 }
944 else {
945 env_cur_tree = hashdata.data;
946 }
947
948 if (last_env_cur_tree != NULL) {
949 if (env_cur_tree->node_parent == NULL) {
950 /* make it one child */
951 if (env_cur_tree != last_env_cur_tree) {
952 if (!is_descendant(env_cur_tree, last_env_cur_tree)) {
953 /* set parent */
954 env_cur_tree->node_parent = last_env_cur_tree;
955 r = carray_add(last_env_cur_tree->node_children,
956 env_cur_tree, NULL);
957 if (r < 0) {
958 res = MAIL_ERROR_MEMORY;
959 goto free_list;
960 }
961 }
962 }
963 }
964 }
965 }
966
967 /* (B) Create a parent/child link between the last reference
968 (or NIL if there are no references) and the current message.
969 If the current message already has a parent, it is probably
970 the result of a truncated References header line, so break
971 the current parent/child link before creating the new
972 correct one.
973 */
974
975 last_env_cur_tree = env_cur_tree;
976
977 if (last_env_cur_tree != NULL) {
978 if (env_tree->node_parent == NULL) {
979 if (last_env_cur_tree != env_tree) {
980 if (!is_descendant(env_tree, last_env_cur_tree)) {
981 /* set parent */
982 env_tree->node_parent = last_env_cur_tree;
983 r = carray_add(last_env_cur_tree->node_children, env_tree, NULL);
984 if (r < 0) {
985 res = MAIL_ERROR_MEMORY;
986 goto free_list;
987 }
988 }
989 }
990 }
991 }
992 }
993 }
994
995 chash_free(msg_id_hash);
996 msg_id_hash = NULL;
997
998 /* (2) Gather together all of the messages that have no parents
999 and make them all children (siblings of one another) of a dummy
1000 parent (the "root").
1001 */
1002
1003 for(cur = 0 ; cur < carray_count(msg_list) ; cur ++) {
1004 struct mailmessage_tree * env_tree;
1005
1006 env_tree = carray_get(msg_list, cur);
1007 if (env_tree->node_parent == NULL) {
1008 r = carray_add(rootlist, env_tree, NULL);
1009 if (r < 0) {
1010 res = MAIL_ERROR_MEMORY;
1011 goto free_list;
1012 }
1013 /* set parent */
1014 env_tree->node_parent = root;
1015 }
1016 }
1017
1018 carray_free(msg_list);
1019 msg_list = NULL;
1020
1021 /* (3) Prune dummy messages from the thread tree.
1022 */
1023
1024 cur = 0;
1025 while (cur < carray_count(rootlist)) {
1026 r = delete_dummy(rootlist, rootlist, cur, &cur);
1027 if (r != MAIL_NO_ERROR) {
1028 res = r;
1029 goto free_list;
1030 }
1031 }
1032
1033 /* (4) Sort the messages under the root (top-level siblings only)
1034 by sent date.
1035 */
1036
1037 r = mail_thread_sort(root, mailthread_tree_timecomp, FALSE);
1038 if (r != MAIL_NO_ERROR) {
1039 res = r;
1040 goto free_list;
1041 }
1042
1043 if (use_subject) {
1044
1045 /* (5) Gather together messages under the root that have the same
1046 extracted subject text.
1047
1048 (A) Create a table for associating extracted subjects with
1049 messages.
1050 */
1051
1052 subject_hash = chash_new(128, CHASH_COPYVALUE);
1053 if (subject_hash == NULL) {
1054 res = MAIL_ERROR_MEMORY;
1055 goto free_list;
1056 }
1057
1058 /*
1059 (B) Populate the subject table with one message per
1060 extracted subject. For each child of the root:
1061 */
1062
1063 for(cur = 0 ; cur < carray_count(rootlist) ; cur ++) {
1064 struct mailmessage_tree * env_tree;
1065 chashdatum key;
1066 chashdatum data;
1067 char * base_subject;
1068 int r;
1069
1070 env_tree = carray_get(rootlist, cur);
1071
1072 /*
1073 (i) Find the subject of this thread by extracting the
1074 base subject from the current message, or its first child
1075 if the current message is a dummy.
1076 */
1077
1078 r = get_thread_subject(default_from, env_tree, &base_subject);
1079
1080 /*
1081 (ii) If the extracted subject is empty, skip this
1082 message.
1083 */
1084
1085 if (r == MAIL_ERROR_SUBJECT_NOT_FOUND) {
1086 /* no subject found */
1087 continue;
1088 }
1089 else if (r == MAIL_NO_ERROR) {
1090 if (* base_subject == '\0') {
1091 /* subject empty */
1092 free(base_subject);
1093 continue;
1094 }
1095 else {
1096 /* do nothing */
1097 }
1098 }
1099 else {
1100 res = r;
1101 goto free_subject_hash;
1102 }
1103
1104 env_tree->node_base_subject = base_subject;
1105
1106 /*
1107 (iii) Lookup the message associated with this extracted
1108 subject in the table.
1109 */
1110
1111 key.data = base_subject;
1112 key.len = strlen(base_subject);
1113
1114 r = chash_get(subject_hash, &key, &data);
1115
1116 if (r < 0) {
1117 /*
1118 (iv) If there is no message in the table with this
1119 subject, add the current message and the extracted
1120 subject to the subject table.
1121 */
1122
1123 data.data = &cur;
1124 data.len = sizeof(cur);
1125
1126 r = chash_set(subject_hash, &key, &data, NULL);
1127 if (r < 0) {
1128 res = MAIL_ERROR_MEMORY;
1129 goto free_subject_hash;
1130 }
1131 }
1132 else {
1133 /*
1134 Otherwise, replace the message in the table with the
1135 current message if the message in the table is not a
1136 dummy AND either of the following criteria are true:
1137 The current message is a dummy, OR
1138 The message in the table is a reply or forward (its
1139 original subject contains a subj-refwd part and/or a
1140 "(fwd)" subj-trailer) and the current message is not.
1141 */
1142 struct mailmessage_tree * msg_in_table;
1143 unsigned int * iter_in_table;
1144 int replace;
1145
1146 iter_in_table = data.data;
1147 msg_in_table = carray_get(rootlist, cur);
1148
1149 replace = FALSE;
1150 /* message is dummy if info is NULL */
1151 if (msg_in_table->node_msg != NULL) {
1152
1153 if (env_tree->node_msg == NULL)
1154 replace = TRUE;
1155 else {
1156 if (env_tree->node_is_reply && !env_tree->node_is_reply)
1157 replace = TRUE;
1158 }
1159 }
1160
1161 if (replace) {
1162 data.data = &cur;
1163 data.len = sizeof(cur);
1164
1165 r = chash_set(subject_hash, &key, &data, NULL);
1166 if (r < 0) {
1167 res = MAIL_ERROR_MEMORY;
1168 goto free_subject_hash;
1169 }
1170 }
1171 }
1172 }
1173
1174 /*
1175 (C) Merge threads with the same subject. For each child of
1176 the root:
1177 */
1178
1179 cur = 0;
1180 while (cur < carray_count(rootlist)) {
1181 struct mailmessage_tree * env_tree;
1182 chashdatum key;
1183 chashdatum data;
1184 int r;
1185 struct mailmessage_tree * main_tree;
1186 unsigned int * main_cur;
1187
1188 env_tree = carray_get(rootlist, cur);
1189
1190 if (env_tree == NULL)
1191 goto next_msg;
1192
1193 /*
1194 (i) Find the subject of this thread as in step 4.B.i
1195 above.
1196 */
1197
1198 /* already done in tree->node_base_subject */
1199
1200 /*
1201 (ii) If the extracted subject is empty, skip this
1202 message.
1203 */
1204
1205 if (env_tree->node_base_subject == NULL)
1206 goto next_msg;
1207
1208 if (* env_tree->node_base_subject == '\0')
1209 goto next_msg;
1210
1211 /*
1212 (iii) Lookup the message associated with this extracted
1213 subject in the table.
1214 */
1215
1216 key.data = env_tree->node_base_subject;
1217 key.len = strlen(env_tree->node_base_subject);
1218
1219 r = chash_get(subject_hash, &key, &data);
1220 if (r < 0)
1221 goto next_msg;
1222
1223 /*
1224 (iv) If the message in the table is the current message,
1225 skip this message.
1226 */
1227
1228 main_cur = data.data;
1229 if (* main_cur == cur)
1230 goto next_msg;
1231
1232 /*
1233 Otherwise, merge the current message with the one in the
1234 table using the following rules:
1235 */
1236
1237 main_tree = carray_get(rootlist, * main_cur);
1238
1239 /*
1240 If both messages are dummies, append the current
1241 message's children to the children of the message in
1242 the table (the children of both messages become
1243 siblings), and then delete the current message.
1244 */
1245
1246 if ((env_tree->node_msg == NULL) && (main_tree->node_msg == NULL)) {
1247 unsigned int old_size;
1248
1249 old_size = carray_count(main_tree->node_children);
1250
1251 r = carray_set_size(main_tree->node_children, old_size +
1252 carray_count(env_tree->node_children));
1253 if (r < 0) {
1254 res = MAIL_ERROR_MEMORY;
1255 goto free_subject_hash;
1256 }
1257
1258 for(i = 0 ; i < carray_count(env_tree->node_children) ; i ++) {
1259 struct mailmessage_tree * child;
1260
1261 child = carray_get(env_tree->node_children, i);
1262 carray_set(main_tree->node_children, old_size + i, child);
1263 /* set parent */
1264 child->node_parent = main_tree;
1265 }
1266 carray_set_size(env_tree->node_children, 0);
1267 /* this is the only case where children can be NULL,
1268 this is before freeing it */
1269 mailmessage_tree_free(env_tree);
1270 carray_delete_fast(rootlist, cur);
1271 }
1272
1273 /*
1274 If the message in the table is a dummy and the current
1275 message is not, make the current message a child of
1276 the message in the table (a sibling of it's children).
1277 */
1278
1279 else if (main_tree->node_msg == NULL) {
1280 r = carray_add(main_tree->node_children, env_tree, NULL);
1281 if (r < 0) {
1282 res = MAIL_ERROR_MEMORY;
1283 goto free_subject_hash;
1284 }
1285 /* set parent */
1286 env_tree->node_parent = main_tree;
1287
1288 carray_delete_fast(rootlist, cur);
1289 }
1290
1291 /*
1292 If the current message is a reply or forward and the
1293 message in the table is not, make the current message
1294 a child of the message in the table (a sibling of it's
1295 children).
1296 */
1297
1298 else if (env_tree->node_is_reply && !main_tree->node_is_reply) {
1299 r = carray_add(main_tree->node_children, env_tree, NULL);
1300 if (r < 0) {
1301 res = MAIL_ERROR_MEMORY;
1302 goto free_subject_hash;
1303 }
1304 /* set parent */
1305 env_tree->node_parent = main_tree;
1306
1307 carray_delete_fast(rootlist, cur);
1308 }
1309
1310 /*
1311 Otherwise, create a new dummy message and make both
1312 the current message and the message in the table
1313 children of the dummy. Then replace the message in
1314 the table with the dummy message.
1315 Note: Subject comparisons are case-insensitive, as
1316 described under "Internationalization
1317 Considerations."
1318 */
1319
1320 else {
1321 struct mailmessage_tree * new_main_tree;
1322 char * base_subject;
1323 unsigned int last;
1324
1325 new_main_tree = mailmessage_tree_new(NULL, (time_t) -1, NULL);
1326 if (new_main_tree == NULL) {
1327 res = MAIL_ERROR_MEMORY;
1328 goto free_subject_hash;
1329 }
1330
1331 /* main_tree->node_base_subject is never NULL */
1332
1333 base_subject = strdup(main_tree->node_base_subject);
1334 if (base_subject == NULL) {
1335 mailmessage_tree_free(new_main_tree);
1336 res = MAIL_ERROR_MEMORY;
1337 goto free_subject_hash;
1338 }
1339
1340 new_main_tree->node_base_subject = base_subject;
1341
1342 r = carray_add(rootlist, new_main_tree, &last);
1343 if (r < 0) {
1344 mailmessage_tree_free(new_main_tree);
1345 res = MAIL_ERROR_MEMORY;
1346 goto free_subject_hash;
1347 }
1348
1349 r = carray_add(new_main_tree->node_children, main_tree, NULL);
1350 if (r < 0) {
1351 res = MAIL_ERROR_MEMORY;
1352 goto free_subject_hash;
1353 }
1354 /* set parent */
1355 main_tree->node_parent = new_main_tree;
1356
1357 carray_delete_fast(rootlist, * main_cur);
1358
1359 r = carray_add(new_main_tree->node_children, env_tree, NULL);
1360 if (r < 0) {
1361 res = MAIL_ERROR_MEMORY;
1362 goto free_subject_hash;
1363 }
1364 /* set parent */
1365 env_tree->node_parent = new_main_tree;
1366
1367 carray_delete_fast(rootlist, cur);
1368
1369 data.data = &last;
1370 data.len = sizeof(last);
1371
1372 r = chash_set(subject_hash, &key, &data, NULL);
1373
1374 if (r < 0) {
1375 res = MAIL_ERROR_MEMORY;
1376 goto free_subject_hash;
1377 }
1378 }
1379
1380 continue;
1381
1382 next_msg:
1383 cur ++;
1384 continue;
1385 }
1386
1387 i = 0;
1388 for(cur = 0 ; cur < carray_count(rootlist) ; cur ++) {
1389 struct mailmessage_tree * env_tree;
1390
1391 env_tree = carray_get(rootlist, cur);
1392 if (env_tree == NULL)
1393 continue;
1394
1395 carray_set(rootlist, i, env_tree);
1396 i ++;
1397 }
1398 carray_set_size(rootlist, i);
1399
1400 chash_free(subject_hash);
1401 }
1402
1403 /*
1404 (6) Traverse the messages under the root and sort each set of
1405 siblings by sent date. Traverse the messages in such a way
1406 that the "youngest" set of siblings are sorted first, and the
1407 "oldest" set of siblings are sorted last (grandchildren are
1408 sorted before children, etc).
1409
1410 In the case of an exact match on
1411 sent date or if either of the Date: headers used in a
1412 comparison can not be parsed, use the order in which the
1413 messages appear in the mailbox (that is, by sequence number) to
1414 determine the order. In the case of a dummy message (which can
1415 only occur with top-level siblings), use its first child for
1416 sorting.
1417 */
1418
1419 if (comp_func != NULL) {
1420 r = mail_thread_sort(root, comp_func, TRUE);
1421 if (r != MAIL_NO_ERROR) {
1422 res = r;
1423 goto free_list;
1424 }
1425 }
1426
1427 * result = root;
1428
1429 return MAIL_NO_ERROR;
1430
1431 free_subject_hash:
1432 chash_free(subject_hash);
1433 free_list:
1434 if (msg_list != NULL) {
1435 for(i = 0 ; i < carray_count(msg_list) ; i ++)
1436 mailmessage_tree_free(carray_get(msg_list, i));
1437 carray_free(msg_list);
1438 }
1439 free_root:
1440 mailmessage_tree_free_recursive(root);
1441 free_hash:
1442 if (msg_id_hash != NULL)
1443 chash_free(msg_id_hash);
1444 err:
1445 return res;
1446}
1447
1448
1449
1450static int
1451mail_build_thread_orderedsubject(char * default_from,
1452 struct mailmessage_list * env_list,
1453 struct mailmessage_tree ** result,
1454 int (* comp_func)(struct mailmessage_tree **,
1455 struct mailmessage_tree **))
1456{
1457 unsigned int i;
1458 carray * rootlist;
1459 unsigned int cur;
1460 struct mailmessage_tree * root;
1461 int res;
1462 int r;
1463 struct mailmessage_tree * current_thread;
1464
1465 root = mailmessage_tree_new(NULL, (time_t) -1, NULL);
1466 if (root == NULL) {
1467 res = MAIL_ERROR_MEMORY;
1468 goto err;
1469 }
1470 rootlist = root->node_children;
1471
1472 /*
1473 The ORDEREDSUBJECT threading algorithm is also referred to as
1474 "poor man's threading."
1475 */
1476
1477 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1478 mailmessage * msg;
1479 struct mailmessage_tree * env_tree;
1480 char * base_subject;
1481 time_t date;
1482
1483 msg = carray_get(env_list->msg_tab, i);
1484
1485 if (msg == NULL)
1486 continue;
1487
1488 if (msg->msg_fields != NULL) {
1489
1490 date = get_date(msg);
1491
1492 env_tree = mailmessage_tree_new(NULL, date, msg);
1493 if (env_tree == NULL) {
1494 res = MAIL_ERROR_MEMORY;
1495 goto free;
1496 }
1497
1498 /* set parent */
1499 env_tree->node_parent = root;
1500 r = carray_add(rootlist, env_tree, NULL);
1501 if (r < 0) {
1502 mailmessage_tree_free(env_tree);
1503 res = MAIL_ERROR_MEMORY;
1504 goto free;
1505 }
1506
1507 r = get_extracted_subject(default_from, env_tree, &base_subject);
1508 switch (r) {
1509 case MAIL_NO_ERROR:
1510 env_tree->node_base_subject = base_subject;
1511 break;
1512
1513 case MAIL_ERROR_SUBJECT_NOT_FOUND:
1514 break;
1515
1516 default:
1517 res = r;
1518 goto free;
1519 }
1520 }
1521 }
1522
1523 /*
1524 The searched messages are sorted by
1525 subject and then by the sent date.
1526 */
1527
1528 r = mail_thread_sort(root, tree_subj_time_comp, FALSE);
1529 if (r != MAIL_NO_ERROR) {
1530 res = r;
1531 goto free;
1532 }
1533
1534 /*
1535 The messages are then split
1536 into separate threads, with each thread containing messages
1537 with the same extracted subject text.
1538 */
1539
1540 current_thread = NULL;
1541
1542 cur = 0;
1543 while (cur < carray_count(rootlist)) {
1544 struct mailmessage_tree * cur_env_tree;
1545
1546 cur_env_tree = carray_get(rootlist, cur);
1547 if (current_thread == NULL) {
1548 current_thread = cur_env_tree;
1549 cur ++;
1550 continue;
1551 }
1552
1553 if ((cur_env_tree->node_base_subject == NULL) ||
1554 (current_thread->node_base_subject == NULL)) {
1555 current_thread = cur_env_tree;
1556 cur ++;
1557 continue;
1558 }
1559
1560 if (strcmp(cur_env_tree->node_base_subject,
1561 current_thread->node_base_subject) == 0) {
1562
1563 /* set parent */
1564 cur_env_tree->node_parent = current_thread;
1565 r = carray_add(current_thread->node_children, cur_env_tree, NULL);
1566 if (r < 0) {
1567 res = MAIL_ERROR_MEMORY;
1568 goto free;
1569 }
1570
1571 carray_delete(rootlist, cur);
1572 }
1573 else
1574 cur ++;
1575 current_thread = cur_env_tree;
1576 }
1577
1578 /*
1579 Finally, the threads are
1580 sorted by the sent date of the first message in the thread.
1581 Note that each message in a thread is a child (as opposed to a
1582 sibling) of the previous message.
1583 */
1584
1585 if (comp_func != NULL) {
1586 r = mail_thread_sort(root, comp_func, FALSE);
1587 if (r != MAIL_NO_ERROR) {
1588 res = r;
1589 goto free;
1590 }
1591 }
1592
1593 * result = root;
1594
1595 return MAIL_NO_ERROR;
1596
1597 free:
1598 mailmessage_tree_free_recursive(root);
1599 err:
1600 return res;
1601}
1602
1603
1604int mail_build_thread(int type, char * default_from,
1605 struct mailmessage_list * env_list,
1606 struct mailmessage_tree ** result,
1607 int (* comp_func)(struct mailmessage_tree **,
1608 struct mailmessage_tree **))
1609{
1610 unsigned int i;
1611
1612 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++)
1613 mailmessage_resolve_single_fields(carray_get(env_list->msg_tab, i));
1614
1615 switch (type) {
1616 case MAIL_THREAD_REFERENCES:
1617 return mail_build_thread_references(default_from,
1618 env_list, result, TRUE, comp_func);
1619
1620 case MAIL_THREAD_REFERENCES_NO_SUBJECT:
1621 return mail_build_thread_references(default_from,
1622 env_list, result, FALSE, comp_func);
1623
1624 case MAIL_THREAD_ORDEREDSUBJECT:
1625 return mail_build_thread_orderedsubject(default_from,
1626 env_list, result, comp_func);
1627
1628 default:
1629 return MAIL_ERROR_NOT_IMPLEMENTED;
1630 }
1631}
diff --git a/kmicromail/libetpan/generic/mailthread.h b/kmicromail/libetpan/generic/mailthread.h
new file mode 100644
index 0000000..e4e33ff
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailthread.h
@@ -0,0 +1,108 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILTHREAD_H
37
38#define MAILTHREAD_H
39
40#include <libetpan/mailthread_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 mail_build_thread constructs a tree with the message using the
48 given style.
49
50 @param type is the type of threading to apply, the value can be
51 MAIL_THREAD_REFERENCES, MAIL_THREAD_REFERENCES_NO_SUBJECT or
52 MAIL_THREAD_ORDEREDSUBJECT.
53
54 @param default_from is the default charset to use whenever the
55 subject is not tagged with a charset. "US-ASCII" can be used
56 if you don't know what to use.
57
58 @param env_list is the message list (with header fields fetched)
59 to use to build the message tree.
60
61 @param result * result) will contain the resulting message tree.
62
63 @param if comp_func is NULL, no sorting algorithm is used.
64
65 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
66 on error
67*/
68
69int mail_build_thread(int type, char * default_from,
70 struct mailmessage_list * env_list,
71 struct mailmessage_tree ** result,
72 int (* comp_func)(struct mailmessage_tree **,
73 struct mailmessage_tree **));
74
75/*
76 mail_thread_sort sort the messages in the message tree, using the
77 given sort function.
78
79 @param tree is the message tree to sort.
80
81 @param comp_func is the sort function to use (this is the same kind of
82 functions than those used for qsort()). mailthread_tree_timecomp can be
83 used for default sort.
84
85 @param sort_sub if this value is 0, only the children of the root message
86 are sorted.
87*/
88
89int mail_thread_sort(struct mailmessage_tree * tree,
90 int (* comp_func)(struct mailmessage_tree **,
91 struct mailmessage_tree **),
92 int sort_sub);
93
94/*
95 mailthread_tree_timecomp is the default sort function.
96
97 The message are compared by date, then by message numbers.
98 The tree are given in (* ptree1) and (* ptree2).
99*/
100
101int mailthread_tree_timecomp(struct mailmessage_tree ** ptree1,
102 struct mailmessage_tree ** ptree2);
103
104#ifdef __cplusplus
105}
106#endif
107
108#endif
diff --git a/kmicromail/libetpan/generic/mailthread_types.c b/kmicromail/libetpan/generic/mailthread_types.c
new file mode 100644
index 0000000..f1c5d37
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailthread_types.c
@@ -0,0 +1,90 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailthread_types.h"
37
38#include "mail.h"
39#include <stdlib.h>
40
41struct mailmessage_tree *
42mailmessage_tree_new(char * node_msgid, time_t node_date,
43 mailmessage * node_msg)
44{
45 struct mailmessage_tree * tree;
46 carray * array;
47
48 array = carray_new(16);
49 if (array == NULL)
50 return NULL;
51
52 tree = malloc(sizeof(* tree));
53 tree->node_parent = NULL;
54 tree->node_date = node_date;
55 tree->node_msgid = node_msgid;
56 tree->node_msg = node_msg;
57 tree->node_children = array;
58 tree->node_base_subject = NULL;
59 tree->node_is_reply = FALSE;
60
61 return tree;
62}
63
64void mailmessage_tree_free(struct mailmessage_tree * tree)
65{
66 if (tree->node_base_subject != NULL)
67 free(tree->node_base_subject);
68
69 if (tree->node_children != NULL)
70 carray_free(tree->node_children);
71 if (tree->node_msgid != NULL)
72 free(tree->node_msgid);
73
74 free(tree);
75}
76
77void mailmessage_tree_free_recursive(struct mailmessage_tree * tree)
78{
79 unsigned int i;
80
81 for(i = 0 ; i < carray_count(tree->node_children) ; i++) {
82 struct mailmessage_tree * child;
83
84 child = carray_get(tree->node_children, i);
85
86 mailmessage_tree_free_recursive(child);
87 }
88
89 mailmessage_tree_free(tree);
90}
diff --git a/kmicromail/libetpan/generic/mailthread_types.h b/kmicromail/libetpan/generic/mailthread_types.h
new file mode 100644
index 0000000..5ef7b46
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mailthread_types.h
@@ -0,0 +1,63 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILTHREAD_TYPES_H
37
38#define MAILTHREAD_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/maildriver_types.h>
45#include <libetpan/mailmessage_types.h>
46
47/*
48 This is the type of tree construction to apply.
49*/
50
51enum {
52 MAIL_THREAD_REFERENCES, /* this is threading using
53 References fields only) */
54 MAIL_THREAD_REFERENCES_NO_SUBJECT, /* this is threading using References
55 fields, then subject */
56 MAIL_THREAD_ORDEREDSUBJECT, /* this is threading using only subject */
57};
58
59#ifdef __cplusplus
60}
61#endif
62
63#endif
diff --git a/kmicromail/libetpan/generic/mboxdriver.c b/kmicromail/libetpan/generic/mboxdriver.c
new file mode 100644
index 0000000..fa3e2ea
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver.c
@@ -0,0 +1,505 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mboxdriver.h"
37
38#include <stdio.h>
39#include <string.h>
40#include <sys/types.h>
41#include <dirent.h>
42#include <unistd.h>
43#include <sys/stat.h>
44#include <ctype.h>
45#include <stdlib.h>
46#include <sys/times.h>
47
48#include "mail.h"
49#include "maildriver_tools.h"
50#include "mailmbox.h"
51#include "mboxdriver_tools.h"
52#include "maildriver.h"
53#include "carray.h"
54#include "mboxdriver_message.h"
55#include "mailmessage.h"
56
57static int mboxdriver_initialize(mailsession * session);
58
59static void mboxdriver_uninitialize(mailsession * session);
60
61static int mboxdriver_parameters(mailsession * session,
62 int id, void * value);
63
64static int mboxdriver_connect_path(mailsession * session, char * path);
65
66static int mboxdriver_logout(mailsession * session);
67
68static int mboxdriver_expunge_folder(mailsession * session);
69
70static int mboxdriver_status_folder(mailsession * session, char * mb,
71 uint32_t * result_messages, uint32_t * result_recent,
72 uint32_t * result_unseen);
73
74static int mboxdriver_messages_number(mailsession * session, char * mb,
75 uint32_t * result);
76
77static int mboxdriver_append_message(mailsession * session,
78 char * message, size_t size);
79
80static int mboxdriver_get_messages_list(mailsession * session,
81 struct mailmessage_list ** result);
82
83static int
84mboxdriver_get_envelopes_list(mailsession * session,
85 struct mailmessage_list * env_list);
86
87static int mboxdriver_remove_message(mailsession * session, uint32_t num);
88
89static int mboxdriver_get_message(mailsession * session,
90 uint32_t num, mailmessage ** result);
91
92static int mboxdriver_get_message_by_uid(mailsession * session,
93 const char * uid,
94 mailmessage ** result);
95
96static mailsession_driver local_mbox_session_driver = {
97 .sess_name = "mbox",
98
99 .sess_initialize = mboxdriver_initialize,
100 .sess_uninitialize = mboxdriver_uninitialize,
101
102 .sess_parameters = mboxdriver_parameters,
103
104 .sess_connect_path = mboxdriver_connect_path,
105 .sess_connect_stream = NULL,
106 .sess_starttls = NULL,
107 .sess_login = NULL,
108 .sess_logout = mboxdriver_logout,
109 .sess_noop = NULL,
110
111 .sess_build_folder_name = NULL,
112 .sess_create_folder = NULL,
113 .sess_delete_folder = NULL,
114 .sess_rename_folder = NULL,
115 .sess_check_folder = NULL,
116 .sess_examine_folder = NULL,
117 .sess_select_folder = NULL,
118 .sess_expunge_folder = mboxdriver_expunge_folder,
119 .sess_status_folder = mboxdriver_status_folder,
120 .sess_messages_number = mboxdriver_messages_number,
121 .sess_recent_number = mboxdriver_messages_number,
122 .sess_unseen_number = mboxdriver_messages_number,
123 .sess_list_folders = NULL,
124 .sess_lsub_folders = NULL,
125 .sess_subscribe_folder = NULL,
126 .sess_unsubscribe_folder = NULL,
127
128 .sess_append_message = mboxdriver_append_message,
129 .sess_copy_message = NULL,
130 .sess_move_message = NULL,
131
132 .sess_get_messages_list = mboxdriver_get_messages_list,
133 .sess_get_envelopes_list = mboxdriver_get_envelopes_list,
134 .sess_remove_message = mboxdriver_remove_message,
135#if 0
136 .sess_search_messages = maildriver_generic_search_messages,
137#endif
138
139 .sess_get_message = mboxdriver_get_message,
140 .sess_get_message_by_uid = mboxdriver_get_message_by_uid,
141};
142
143mailsession_driver * mbox_session_driver = &local_mbox_session_driver;
144
145static inline struct mbox_session_state_data * get_data(mailsession * session)
146{
147 return session->sess_data;
148}
149
150static inline struct mailmbox_folder * get_mbox_session(mailsession * session)
151{
152 return get_data(session)->mbox_folder;
153}
154
155static int mboxdriver_initialize(mailsession * session)
156{
157 struct mbox_session_state_data * data;
158
159 data = malloc(sizeof(* data));
160 if (data == NULL)
161 goto err;
162
163 data->mbox_folder = NULL;
164
165 data->mbox_force_read_only = FALSE;
166 data->mbox_force_no_uid = TRUE;
167
168 session->sess_data = data;
169
170 return MAIL_NO_ERROR;
171
172 err:
173 return MAIL_ERROR_MEMORY;
174}
175
176static void free_state(struct mbox_session_state_data * mbox_data)
177{
178 if (mbox_data->mbox_folder != NULL) {
179 mailmbox_done(mbox_data->mbox_folder);
180 mbox_data->mbox_folder = NULL;
181 }
182}
183
184static void mboxdriver_uninitialize(mailsession * session)
185{
186 struct mbox_session_state_data * data;
187
188 data = get_data(session);
189
190 free_state(data);
191
192 free(data);
193}
194
195static int mboxdriver_parameters(mailsession * session,
196 int id, void * value)
197{
198 struct mbox_session_state_data * data;
199
200 data = get_data(session);
201
202 switch (id) {
203 case MBOXDRIVER_SET_READ_ONLY:
204 {
205 int * param;
206
207 param = value;
208
209 data->mbox_force_read_only = * param;
210 return MAIL_NO_ERROR;
211 }
212
213 case MBOXDRIVER_SET_NO_UID:
214 {
215 int * param;
216
217 param = value;
218
219 data->mbox_force_no_uid = * param;
220 return MAIL_NO_ERROR;
221 }
222 }
223
224 return MAIL_ERROR_INVAL;
225}
226
227
228static int mboxdriver_connect_path(mailsession * session, char * path)
229{
230 struct mbox_session_state_data * mbox_data;
231 struct mailmbox_folder * folder;
232 int r;
233
234 mbox_data = get_data(session);
235
236 if (mbox_data->mbox_folder != NULL)
237 return MAIL_ERROR_BAD_STATE;
238
239 r = mailmbox_init(path,
240 mbox_data->mbox_force_read_only,
241 mbox_data->mbox_force_no_uid,
242 0,
243 &folder);
244
245 if (r != MAILMBOX_NO_ERROR)
246 return mboxdriver_mbox_error_to_mail_error(r);
247
248 mbox_data->mbox_folder = folder;
249
250 return MAIL_NO_ERROR;
251}
252
253static int mboxdriver_logout(mailsession * session)
254{
255 struct mbox_session_state_data * mbox_data;
256
257 mbox_data = get_data(session);
258
259 if (mbox_data->mbox_folder == NULL)
260 return MAIL_ERROR_BAD_STATE;
261
262 free_state(mbox_data);
263
264 mbox_data->mbox_folder = NULL;
265
266 return MAIL_NO_ERROR;
267}
268
269static int mboxdriver_expunge_folder(mailsession * session)
270{
271 int r;
272 struct mbox_session_state_data * mbox_data;
273
274 mbox_data = get_data(session);
275
276 if (mbox_data->mbox_folder == NULL)
277 return MAIL_ERROR_BAD_STATE;
278
279 r = mailmbox_expunge(mbox_data->mbox_folder);
280 if (r != MAILMBOX_NO_ERROR)
281 return mboxdriver_mbox_error_to_mail_error(r);
282
283 return MAIL_NO_ERROR;
284}
285
286static int mboxdriver_status_folder(mailsession * session, char * mb,
287 uint32_t * result_messages, uint32_t * result_recent,
288 uint32_t * result_unseen)
289{
290 uint32_t count;
291 int r;
292
293 r = mboxdriver_messages_number(session, mb, &count);
294 if (r != MAIL_NO_ERROR)
295 return r;
296
297 * result_messages = count;
298 * result_recent = count;
299 * result_unseen = count;
300
301 return MAIL_NO_ERROR;
302}
303
304static int mboxdriver_messages_number(mailsession * session, char * mb,
305 uint32_t * result)
306{
307 struct mailmbox_folder * folder;
308 int r;
309
310 folder = get_mbox_session(session);
311 if (folder == NULL)
312 return MAIL_ERROR_STATUS;
313
314 r = mailmbox_validate_read_lock(folder);
315 if (r != MAIL_NO_ERROR)
316 return r;
317
318 mailmbox_read_unlock(folder);
319
320 * result = carray_count(folder->mb_tab) - folder->mb_deleted_count;
321
322 return MAILMBOX_NO_ERROR;
323}
324
325/* messages operations */
326
327static int mboxdriver_append_message(mailsession * session,
328 char * message, size_t size)
329{
330 int r;
331 struct mailmbox_folder * folder;
332
333 folder = get_mbox_session(session);
334 if (folder == NULL)
335 return MAIL_ERROR_APPEND;
336
337 r = mailmbox_append_message(folder, message, size);
338
339 switch (r) {
340 case MAILMBOX_ERROR_FILE:
341 return MAIL_ERROR_DISKSPACE;
342 default:
343 return mboxdriver_mbox_error_to_mail_error(r);
344 }
345}
346
347static int mboxdriver_get_messages_list(mailsession * session,
348 struct mailmessage_list ** result)
349{
350 struct mailmbox_folder * folder;
351 int res;
352
353 folder = get_mbox_session(session);
354 if (folder == NULL) {
355 res = MAIL_ERROR_BAD_STATE;
356 goto err;
357 }
358
359 return mbox_get_messages_list(folder, session, mbox_message_driver, result);
360
361 err:
362 return res;
363}
364
365static int
366mboxdriver_get_envelopes_list(mailsession * session,
367 struct mailmessage_list * env_list)
368{
369 struct mailmbox_folder * folder;
370 unsigned int i;
371 int r;
372 int res;
373
374 folder = get_mbox_session(session);
375 if (folder == NULL) {
376 res = MAIL_ERROR_BAD_STATE;
377 goto err;
378 }
379
380 r = mailmbox_validate_read_lock(folder);
381 if (r != MAILMBOX_NO_ERROR) {
382 res = mboxdriver_mbox_error_to_mail_error(r);
383 goto err;
384 }
385
386 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
387 mailmessage * msg;
388 struct mailimf_fields * fields;
389 char * headers;
390 size_t headers_len;
391 size_t cur_token;
392
393 msg = carray_get(env_list->msg_tab, i);
394 if (msg == NULL)
395 continue;
396
397 if (msg->msg_fields != NULL)
398 continue;
399
400 r = mailmbox_fetch_msg_headers_no_lock(folder,
401 msg->msg_index, &headers, &headers_len);
402 if (r != MAILMBOX_NO_ERROR) {
403 res = mboxdriver_mbox_error_to_mail_error(r);
404 goto unlock;
405 }
406
407 cur_token = 0;
408 r = mailimf_envelope_fields_parse(headers, headers_len,
409 &cur_token, &fields);
410
411 if (r != MAILIMF_NO_ERROR)
412 continue;
413
414 msg->msg_fields = fields;
415 }
416
417 mailmbox_read_unlock(folder);
418
419 return MAIL_NO_ERROR;
420
421 unlock:
422 mailmbox_read_unlock(folder);
423 err:
424 return res;
425}
426
427
428static int mboxdriver_remove_message(mailsession * session, uint32_t num)
429{
430 int r;
431 struct mailmbox_folder * folder;
432
433 folder = get_mbox_session(session);
434 if (folder == NULL)
435 return MAIL_ERROR_DELETE;
436
437 r = mailmbox_delete_msg(folder, num);
438
439 return mboxdriver_mbox_error_to_mail_error(r);
440}
441
442static int mboxdriver_get_message(mailsession * session,
443 uint32_t num, mailmessage ** result)
444{
445 mailmessage * msg_info;
446 int r;
447
448 msg_info = mailmessage_new();
449 if (msg_info == NULL)
450 return MAIL_ERROR_MEMORY;
451
452 r = mailmessage_init(msg_info, session, mbox_message_driver, num, 0);
453 if (r != MAIL_NO_ERROR) {
454 mailmessage_free(msg_info);
455 return r;
456 }
457
458 * result = msg_info;
459
460 return MAIL_NO_ERROR;
461}
462
463static int mboxdriver_get_message_by_uid(mailsession * session,
464 const char * uid,
465 mailmessage ** result)
466{
467 uint32_t num;
468 char * p;
469 chashdatum key;
470 chashdatum data;
471 struct mailmbox_msg_info * info;
472 struct mailmbox_folder * folder;
473 int r;
474
475 if (uid == NULL)
476 return MAIL_ERROR_INVAL;
477
478 num = strtoul(uid, &p, 10);
479 if (p == uid || * p != '-')
480 return MAIL_ERROR_INVAL;
481
482 folder = get_mbox_session(session);
483 if (folder == NULL)
484 return MAIL_ERROR_BAD_STATE;
485
486 key.data = &num;
487 key.len = sizeof(num);
488
489 r = chash_get(folder->mb_hash, &key, &data);
490 if (r == 0) {
491 char * body_len_p = p + 1;
492 size_t body_len;
493
494 info = data.data;
495 /* Check if the cached message has the same UID */
496 body_len = strtoul(body_len_p, &p, 10);
497 if (p == body_len_p || * p != '\0')
498 return MAIL_ERROR_INVAL;
499
500 if (body_len == info->msg_body_len)
501 return mboxdriver_get_message(session, num, result);
502 }
503
504 return MAIL_ERROR_MSG_NOT_FOUND;
505}
diff --git a/kmicromail/libetpan/generic/mboxdriver.h b/kmicromail/libetpan/generic/mboxdriver.h
new file mode 100644
index 0000000..c598026
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MBOXDRIVER_H
37
38#define MBOXDRIVER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mboxdriver_types.h>
45
46extern mailsession_driver * mbox_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/mboxdriver_cached.c b/kmicromail/libetpan/generic/mboxdriver_cached.c
new file mode 100644
index 0000000..07871fa
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_cached.c
@@ -0,0 +1,1253 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mboxdriver_cached.h"
37
38#include <stdio.h>
39#include <string.h>
40#include <dirent.h>
41#include <unistd.h>
42#include <ctype.h>
43#include <sys/types.h>
44#include <sys/stat.h>
45#include <fcntl.h>
46#include <stdlib.h>
47
48#include "mail.h"
49#include "mail_cache_db.h"
50#include "mboxdriver.h"
51#include "mboxdriver_tools.h"
52#include "maildriver_tools.h"
53#include "mailmbox.h"
54#include "maildriver.h"
55#include "carray.h"
56#include "generic_cache.h"
57#include "imfcache.h"
58#include "mboxdriver_cached_message.h"
59#include "libetpan-config.h"
60
61static int mboxdriver_cached_initialize(mailsession * session);
62
63static void mboxdriver_cached_uninitialize(mailsession * session);
64
65static int mboxdriver_cached_parameters(mailsession * session,
66 int id, void * value);
67
68static int mboxdriver_cached_connect_path(mailsession * session, char * path);
69
70static int mboxdriver_cached_logout(mailsession * session);
71
72static int mboxdriver_cached_check_folder(mailsession * session);
73
74static int mboxdriver_cached_expunge_folder(mailsession * session);
75
76static int mboxdriver_cached_status_folder(mailsession * session, char * mb,
77 uint32_t * result_messages, uint32_t * result_recent,
78 uint32_t * result_unseen);
79static int mboxdriver_cached_messages_number(mailsession * session, char * mb,
80 uint32_t * result);
81static int mboxdriver_cached_recent_number(mailsession * session, char * mb,
82 uint32_t * result);
83static int mboxdriver_cached_unseen_number(mailsession * session, char * mb,
84 uint32_t * result);
85
86static int mboxdriver_cached_append_message(mailsession * session,
87 char * message, size_t size);
88
89static int
90mboxdriver_cached_get_messages_list(mailsession * session,
91 struct mailmessage_list ** result);
92
93static int
94mboxdriver_cached_get_envelopes_list(mailsession * session,
95 struct mailmessage_list * env_list);
96
97static int mboxdriver_cached_remove_message(mailsession * session,
98 uint32_t num);
99
100static int mboxdriver_cached_get_message(mailsession * session,
101 uint32_t num, mailmessage ** result);
102
103static int mboxdriver_cached_get_message_by_uid(mailsession * session,
104 const char * uid,
105 mailmessage ** result);
106
107static mailsession_driver local_mbox_cached_session_driver = {
108 .sess_name = "mbox-cached",
109
110 .sess_initialize = mboxdriver_cached_initialize,
111 .sess_uninitialize = mboxdriver_cached_uninitialize,
112
113 .sess_parameters = mboxdriver_cached_parameters,
114
115 .sess_connect_path = mboxdriver_cached_connect_path,
116 .sess_connect_stream = NULL,
117 .sess_starttls = NULL,
118 .sess_login = NULL,
119 .sess_logout = mboxdriver_cached_logout,
120 .sess_noop = NULL,
121
122 .sess_build_folder_name = NULL,
123 .sess_create_folder = NULL,
124 .sess_delete_folder = NULL,
125 .sess_rename_folder = NULL,
126 .sess_check_folder = mboxdriver_cached_check_folder,
127 .sess_examine_folder = NULL,
128 .sess_select_folder = NULL,
129 .sess_expunge_folder = mboxdriver_cached_expunge_folder,
130 .sess_status_folder = mboxdriver_cached_status_folder,
131 .sess_messages_number = mboxdriver_cached_messages_number,
132 .sess_recent_number = mboxdriver_cached_recent_number,
133 .sess_unseen_number = mboxdriver_cached_unseen_number,
134 .sess_list_folders = NULL,
135 .sess_lsub_folders = NULL,
136 .sess_subscribe_folder = NULL,
137 .sess_unsubscribe_folder = NULL,
138
139 .sess_append_message = mboxdriver_cached_append_message,
140 .sess_copy_message = NULL,
141 .sess_move_message = NULL,
142
143 .sess_get_messages_list = mboxdriver_cached_get_messages_list,
144 .sess_get_envelopes_list = mboxdriver_cached_get_envelopes_list,
145 .sess_remove_message = mboxdriver_cached_remove_message,
146#if 0
147 .sess_search_messages = maildriver_generic_search_messages,
148#endif
149
150 .sess_get_message = mboxdriver_cached_get_message,
151 .sess_get_message_by_uid = mboxdriver_cached_get_message_by_uid,
152};
153
154mailsession_driver * mbox_cached_session_driver =
155&local_mbox_cached_session_driver;
156
157
158#define ENV_NAME "env.db"
159#define FLAGS_NAME "flags.db"
160
161
162
163static int mbox_error_to_mail_error(int error)
164{
165 switch (error) {
166 case MAILMBOX_NO_ERROR:
167 return MAIL_NO_ERROR;
168
169 case MAILMBOX_ERROR_PARSE:
170 return MAIL_ERROR_PARSE;
171
172 case MAILMBOX_ERROR_INVAL:
173 return MAIL_ERROR_INVAL;
174
175 case MAILMBOX_ERROR_FILE_NOT_FOUND:
176 return MAIL_ERROR_PARSE;
177
178 case MAILMBOX_ERROR_MEMORY:
179 return MAIL_ERROR_MEMORY;
180
181 case MAILMBOX_ERROR_TEMPORARY_FILE:
182 return MAIL_ERROR_PARSE;
183
184 case MAILMBOX_ERROR_FILE:
185 return MAIL_ERROR_FILE;
186
187 case MAILMBOX_ERROR_MSG_NOT_FOUND:
188 return MAIL_ERROR_MSG_NOT_FOUND;
189
190 case MAILMBOX_ERROR_READONLY:
191 return MAIL_ERROR_READONLY;
192
193 default:
194 return MAIL_ERROR_INVAL;
195 }
196}
197
198
199
200
201static inline struct mbox_cached_session_state_data *
202get_cached_data(mailsession * session)
203{
204 return session->sess_data;
205}
206
207static inline mailsession * get_ancestor(mailsession * session)
208{
209 return get_cached_data(session)->mbox_ancestor;
210}
211
212static inline struct mbox_session_state_data *
213get_ancestor_data(mailsession * session)
214{
215 return get_ancestor(session)->sess_data;
216}
217
218static inline struct mailmbox_folder *
219get_mbox_session(mailsession * session)
220{
221 return get_ancestor_data(session)->mbox_folder;
222}
223
224static int mboxdriver_cached_initialize(mailsession * session)
225{
226 struct mbox_cached_session_state_data * cached_data;
227 struct mbox_session_state_data * mbox_data;
228
229 cached_data = malloc(sizeof(* cached_data));
230 if (cached_data == NULL)
231 goto err;
232
233 cached_data->mbox_flags_store = mail_flags_store_new();
234 if (cached_data->mbox_flags_store == NULL)
235 goto free;
236
237 cached_data->mbox_ancestor = mailsession_new(mbox_session_driver);
238 if (cached_data->mbox_ancestor == NULL)
239 goto free_store;
240
241 cached_data->mbox_quoted_mb = NULL;
242 /*
243 UID must be enabled to take advantage of the cache
244 */
245 mbox_data = cached_data->mbox_ancestor->sess_data;
246 mbox_data->mbox_force_no_uid = FALSE;
247
248 session->sess_data = cached_data;
249
250 return MAIL_NO_ERROR;
251
252 free_store:
253 mail_flags_store_free(cached_data->mbox_flags_store);
254 free:
255 free(cached_data);
256 err:
257 return MAIL_ERROR_MEMORY;
258}
259
260static void free_state(struct mbox_cached_session_state_data * mbox_data)
261{
262 if (mbox_data->mbox_quoted_mb) {
263 free(mbox_data->mbox_quoted_mb);
264 mbox_data->mbox_quoted_mb = NULL;
265 }
266}
267
268static int mbox_flags_store_process(char * flags_directory, char * quoted_mb,
269 struct mail_flags_store * flags_store)
270{
271 char filename_flags[PATH_MAX];
272 struct mail_cache_db * cache_db_flags;
273 MMAPString * mmapstr;
274 unsigned int i;
275 int r;
276 int res;
277
278 if (carray_count(flags_store->fls_tab) == 0)
279 return MAIL_NO_ERROR;
280
281 if (quoted_mb == NULL)
282 return MAIL_NO_ERROR;
283
284 snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s",
285 flags_directory, MAIL_DIR_SEPARATOR, quoted_mb,
286 MAIL_DIR_SEPARATOR, FLAGS_NAME);
287
288 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
289 if (r < 0) {
290 res = MAIL_ERROR_FILE;
291 goto err;
292 }
293
294 mmapstr = mmap_string_new("");
295 if (mmapstr == NULL) {
296 res = MAIL_ERROR_MEMORY;
297 goto close_db_flags;
298 }
299
300 for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
301 mailmessage * msg;
302
303 msg = carray_get(flags_store->fls_tab, i);
304
305 r = mboxdriver_write_cached_flags(cache_db_flags, mmapstr,
306 msg->msg_uid, msg->msg_flags);
307 if (r != MAIL_NO_ERROR) {
308 /* ignore errors */
309 }
310 }
311
312 mmap_string_free(mmapstr);
313 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
314
315 mail_flags_store_clear(flags_store);
316
317 return MAIL_NO_ERROR;
318
319 close_db_flags:
320 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
321 err:
322 return res;
323}
324
325static void mboxdriver_cached_uninitialize(mailsession * session)
326{
327 struct mbox_cached_session_state_data * data;
328
329 data = get_cached_data(session);
330
331 mbox_flags_store_process(data->mbox_flags_directory,
332 data->mbox_quoted_mb,
333 data->mbox_flags_store);
334
335 mail_flags_store_free(data->mbox_flags_store);
336
337 free_state(data);
338 mailsession_free(data->mbox_ancestor);
339 free(data);
340
341 session->sess_data = NULL;
342}
343
344static int mboxdriver_cached_parameters(mailsession * session,
345 int id, void * value)
346{
347 struct mbox_cached_session_state_data * data;
348 int r;
349
350 data = get_cached_data(session);
351
352 switch (id) {
353 case MBOXDRIVER_CACHED_SET_CACHE_DIRECTORY:
354 strncpy(data->mbox_cache_directory, value, PATH_MAX);
355 data->mbox_cache_directory[PATH_MAX - 1] = '\0';
356
357 r = generic_cache_create_dir(data->mbox_cache_directory);
358 if (r != MAIL_NO_ERROR)
359 return r;
360
361 return MAIL_NO_ERROR;
362
363 case MBOXDRIVER_CACHED_SET_FLAGS_DIRECTORY:
364 strncpy(data->mbox_flags_directory, value, PATH_MAX);
365 data->mbox_flags_directory[PATH_MAX - 1] = '\0';
366
367 r = generic_cache_create_dir(data->mbox_flags_directory);
368 if (r != MAIL_NO_ERROR)
369 return r;
370
371 return MAIL_NO_ERROR;
372
373 case MBOXDRIVER_SET_NO_UID:
374 return MAIL_ERROR_INVAL;
375
376 default:
377 return mailsession_parameters(data->mbox_ancestor, id, value);
378 }
379}
380
381
382static int get_cache_directory(mailsession * session,
383 char * path, char ** result)
384{
385 char * quoted_mb;
386 char dirname[PATH_MAX];
387 int res;
388 int r;
389 struct mbox_cached_session_state_data * cached_data;
390
391 cached_data = get_cached_data(session);
392
393 quoted_mb = maildriver_quote_mailbox(path);
394 if (quoted_mb == NULL) {
395 res = MAIL_ERROR_MEMORY;
396 goto err;
397 }
398
399 snprintf(dirname, PATH_MAX, "%s%c%s",
400 cached_data->mbox_cache_directory, MAIL_DIR_SEPARATOR, quoted_mb);
401
402 r = generic_cache_create_dir(dirname);
403 if (r != MAIL_NO_ERROR) {
404 res = r;
405 goto free;
406 }
407
408 snprintf(dirname, PATH_MAX, "%s%c%s",
409 cached_data->mbox_flags_directory, MAIL_DIR_SEPARATOR, quoted_mb);
410
411 r = generic_cache_create_dir(dirname);
412 if (r != MAIL_NO_ERROR) {
413 res = r;
414 goto free;
415 }
416
417 * result = quoted_mb;
418
419 return MAIL_NO_ERROR;
420
421 free:
422 free(quoted_mb);
423 err:
424 return res;
425}
426
427
428
429
430#define FILENAME_MAX_UID "max-uid"
431
432/* write max uid current value */
433
434static int write_max_uid_value(mailsession * session)
435{
436 int r;
437 char filename[PATH_MAX];
438 FILE * f;
439 int res;
440
441#if 0
442 struct mbox_session_state_data * mbox_data;
443#endif
444 struct mbox_cached_session_state_data * cached_data;
445 int fd;
446
447 MMAPString * mmapstr;
448 size_t cur_token;
449 struct mailmbox_folder * folder;
450
451 /* expunge the mailbox */
452
453#if 0
454 mbox_data = get_ancestor(session)->data;
455#endif
456 folder = get_mbox_session(session);
457
458 r = mailmbox_validate_write_lock(folder);
459 if (r != MAILMBOX_NO_ERROR) {
460 res = mbox_error_to_mail_error(r);
461 goto err;
462 }
463
464 r = mailmbox_expunge_no_lock(folder);
465 if (r != MAILMBOX_NO_ERROR) {
466 res = r;
467 goto unlock;
468 }
469
470 cached_data = get_cached_data(session);
471
472 snprintf(filename, PATH_MAX, "%s%c%s%c%s",
473 cached_data->mbox_flags_directory, MAIL_DIR_SEPARATOR,
474 cached_data->mbox_quoted_mb, MAIL_DIR_SEPARATOR, FILENAME_MAX_UID);
475
476 fd = creat(filename, S_IRUSR | S_IWUSR);
477 if (fd < 0) {
478 res = MAIL_ERROR_FILE;
479 goto err;
480 }
481
482 f = fdopen(fd, "w");
483 if (f == NULL) {
484 close(fd);
485 res = MAIL_ERROR_FILE;
486 goto unlock;
487 }
488
489 mmapstr = mmap_string_new("");
490 if (mmapstr == NULL) {
491 res = MAIL_ERROR_MEMORY;
492 goto close;
493 }
494
495 r = mail_serialize_clear(mmapstr, &cur_token);
496 if (r != MAIL_NO_ERROR) {
497 res = r;
498 goto free_mmapstr;
499 }
500
501 r = mailimf_cache_int_write(mmapstr, &cur_token,
502 folder->mb_written_uid);
503 if (r != MAIL_NO_ERROR) {
504 res = r;
505 goto free_mmapstr;
506 }
507
508 fwrite(mmapstr->str, 1, mmapstr->len, f);
509
510 mmap_string_free(mmapstr);
511 fclose(f);
512 mailmbox_write_unlock(folder);
513
514 return MAIL_NO_ERROR;
515
516 free_mmapstr:
517 mmap_string_free(mmapstr);
518 close:
519 fclose(f);
520 unlock:
521 mailmbox_read_unlock(folder);
522 err:
523 return res;
524}
525
526static int read_max_uid_value(mailsession * session, uint32_t * result)
527{
528 int r;
529 char filename[PATH_MAX];
530 FILE * f;
531 uint32_t written_uid;
532 int res;
533
534 struct mbox_cached_session_state_data * cached_data;
535
536 MMAPString * mmapstr;
537 size_t cur_token;
538 char buf[sizeof(uint32_t)];
539 size_t read_size;
540
541 cached_data = get_cached_data(session);
542
543 snprintf(filename, PATH_MAX, "%s%c%s%c%s",
544 cached_data->mbox_flags_directory, MAIL_DIR_SEPARATOR,
545 cached_data->mbox_quoted_mb, MAIL_DIR_SEPARATOR, FILENAME_MAX_UID);
546
547 f = fopen(filename, "r");
548 if (f == NULL) {
549 res = MAIL_ERROR_FILE;
550 goto err;
551 }
552
553 read_size = fread(buf, 1, sizeof(uint32_t), f);
554
555 mmapstr = mmap_string_new_len(buf, read_size);
556 if (mmapstr == NULL) {
557 res = MAIL_ERROR_MEMORY;
558 goto close;
559 }
560
561 cur_token = 0;
562
563 r = mailimf_cache_int_read(mmapstr, &cur_token, &written_uid);
564 if (r != MAIL_NO_ERROR) {
565 fclose(f);
566 res = r;
567 goto free_mmapstr;
568 }
569
570 mmap_string_free(mmapstr);
571 fclose(f);
572
573 * result = written_uid;
574
575 return MAIL_NO_ERROR;
576
577 free_mmapstr:
578 mmap_string_free(mmapstr);
579 close:
580 fclose(f);
581 err:
582 return res;
583}
584
585static int mboxdriver_cached_connect_path(mailsession * session, char * path)
586{
587 int r;
588 int res;
589 char * quoted_mb;
590 struct mbox_cached_session_state_data * cached_data;
591 struct mbox_session_state_data * ancestor_data;
592 struct mailmbox_folder * folder;
593 uint32_t written_uid;
594
595 folder = get_mbox_session(session);
596 if (folder != NULL) {
597 res = MAIL_ERROR_BAD_STATE;
598 goto err;
599 }
600
601 r = get_cache_directory(session, path, &quoted_mb);
602 if (r != MAIL_NO_ERROR) {
603 res = r;
604 goto err;
605 }
606
607 cached_data = get_cached_data(session);
608 free_state(cached_data);
609
610 cached_data->mbox_quoted_mb = quoted_mb;
611
612 written_uid = 0;
613 r = read_max_uid_value(session, &written_uid);
614 /* ignore errors */
615
616 ancestor_data = get_ancestor_data(session);
617
618 r = mailmbox_init(path,
619 ancestor_data->mbox_force_read_only,
620 ancestor_data->mbox_force_no_uid,
621 written_uid,
622 &folder);
623
624 if (r != MAILMBOX_NO_ERROR) {
625 cached_data->mbox_quoted_mb = NULL;
626
627 res = mboxdriver_mbox_error_to_mail_error(r);
628 goto free;
629 }
630
631 ancestor_data->mbox_folder = folder;
632
633 return MAIL_NO_ERROR;
634
635 free:
636 free(quoted_mb);
637 err:
638 return res;
639}
640
641
642static int mboxdriver_cached_logout(mailsession * session)
643{
644 struct mbox_cached_session_state_data * cached_data;
645 int r;
646
647 r = write_max_uid_value(session);
648
649 cached_data = get_cached_data(session);
650
651 mbox_flags_store_process(cached_data->mbox_flags_directory,
652 cached_data->mbox_quoted_mb,
653 cached_data->mbox_flags_store);
654
655 r = mailsession_logout(get_ancestor(session));
656 if (r != MAIL_NO_ERROR)
657 return r;
658
659 free_state(cached_data);
660
661 return MAIL_NO_ERROR;
662}
663
664static int mboxdriver_cached_check_folder(mailsession * session)
665{
666 struct mbox_cached_session_state_data * cached_data;
667
668 cached_data = get_cached_data(session);
669
670 mbox_flags_store_process(cached_data->mbox_flags_directory,
671 cached_data->mbox_quoted_mb,
672 cached_data->mbox_flags_store);
673
674 return MAIL_NO_ERROR;
675}
676
677static int mboxdriver_cached_expunge_folder(mailsession * session)
678{
679 struct mailmbox_folder * folder;
680 int res;
681 char filename_flags[PATH_MAX];
682 struct mail_cache_db * cache_db_flags;
683 MMAPString * mmapstr;
684 struct mbox_cached_session_state_data * data;
685 int r;
686 unsigned int i;
687
688 folder = get_mbox_session(session);
689 if (folder == NULL) {
690 res = MAIL_ERROR_BAD_STATE;
691 goto err;
692 }
693
694 data = get_cached_data(session);
695 if (data->mbox_quoted_mb == NULL) {
696 res = MAIL_ERROR_BAD_STATE;
697 goto err;
698 }
699
700 mbox_flags_store_process(data->mbox_flags_directory,
701 data->mbox_quoted_mb,
702 data->mbox_flags_store);
703
704 snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s",
705 data->mbox_flags_directory, MAIL_DIR_SEPARATOR, data->mbox_quoted_mb,
706 MAIL_DIR_SEPARATOR, FLAGS_NAME);
707
708 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
709 if (r < 0) {
710 res = MAIL_ERROR_FILE;
711 goto err;
712 }
713
714 mmapstr = mmap_string_new("");
715 if (mmapstr == NULL) {
716 res = MAIL_ERROR_MEMORY;
717 goto close_db_flags;
718 }
719
720 for(i = 0 ; i < carray_count(folder->mb_tab) ; i ++) {
721 struct mailmbox_msg_info * msg_info;
722 struct mail_flags * flags;
723
724 msg_info = carray_get(folder->mb_tab, i);
725 if (msg_info == NULL)
726 continue;
727
728 if (msg_info->msg_deleted)
729 continue;
730
731 r = mboxdriver_get_cached_flags(cache_db_flags, mmapstr,
732 session, msg_info->msg_uid, &flags);
733 if (r != MAIL_NO_ERROR)
734 continue;
735
736 if (flags->fl_flags & MAIL_FLAG_DELETED) {
737 r = mailmbox_delete_msg(folder, msg_info->msg_uid);
738 }
739
740 mail_flags_free(flags);
741 }
742
743 mmap_string_free(mmapstr);
744 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
745
746 r = mailmbox_expunge(folder);
747
748 return MAIL_NO_ERROR;
749
750 close_db_flags:
751 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
752 err:
753 return res;
754}
755
756static int mboxdriver_cached_status_folder(mailsession * session, char * mb,
757 uint32_t * result_messages, uint32_t * result_recent,
758 uint32_t * result_unseen)
759{
760 struct mailmbox_folder * folder;
761 int res;
762 char filename_flags[PATH_MAX];
763 struct mail_cache_db * cache_db_flags;
764 MMAPString * mmapstr;
765 struct mbox_cached_session_state_data * data;
766 int r;
767 unsigned int i;
768 uint32_t recent;
769 uint32_t unseen;
770 uint32_t num;
771
772 num = 0;
773 recent = 0;
774 unseen = 0;
775
776 folder = get_mbox_session(session);
777 if (folder == NULL) {
778 res = MAIL_ERROR_BAD_STATE;
779 goto err;
780 }
781
782 data = get_cached_data(session);
783 if (data->mbox_quoted_mb == NULL) {
784 res = MAIL_ERROR_BAD_STATE;
785 goto err;
786 }
787
788 r = mailmbox_validate_read_lock(folder);
789 if (r != MAIL_NO_ERROR) {
790 res = MAIL_ERROR_BAD_STATE;
791 goto err;
792 }
793
794 mailmbox_read_unlock(folder);
795
796 mbox_flags_store_process(data->mbox_flags_directory, data->mbox_quoted_mb,
797 data->mbox_flags_store);
798
799 snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s",
800 data->mbox_flags_directory, MAIL_DIR_SEPARATOR, data->mbox_quoted_mb,
801 MAIL_DIR_SEPARATOR, FLAGS_NAME);
802
803 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
804 if (r < 0) {
805 res = MAIL_ERROR_FILE;
806 goto err;
807 }
808
809 mmapstr = mmap_string_new("");
810 if (mmapstr == NULL) {
811 res = MAIL_ERROR_MEMORY;
812 goto close_db_flags;
813 }
814
815 for(i = 0 ; i < carray_count(folder->mb_tab) ; i ++) {
816 struct mailmbox_msg_info * msg_info;
817 struct mail_flags * flags;
818
819 msg_info = carray_get(folder->mb_tab, i);
820 if (msg_info == NULL)
821 continue;
822
823 if (msg_info->msg_deleted)
824 continue;
825
826 r = mboxdriver_get_cached_flags(cache_db_flags, mmapstr,
827 session, msg_info->msg_uid, &flags);
828 if (r != MAIL_NO_ERROR) {
829 recent ++;
830 unseen ++;
831 num ++;
832 continue;
833 }
834
835 if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) {
836 recent ++;
837 }
838 if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) {
839 unseen ++;
840 }
841
842 num ++;
843
844 mail_flags_free(flags);
845 }
846
847 mmap_string_free(mmapstr);
848 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
849
850 * result_messages = num;
851 * result_recent = recent;
852 * result_unseen = unseen;
853
854 return MAIL_NO_ERROR;
855
856 close_db_flags:
857 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
858 err:
859 return res;
860}
861
862static int mboxdriver_cached_messages_number(mailsession * session, char * mb,
863 uint32_t * result)
864{
865 return mailsession_messages_number(get_ancestor(session), mb, result);
866}
867
868
869static int mboxdriver_cached_recent_number(mailsession * session, char * mb,
870 uint32_t * result)
871{
872 uint32_t messages;
873 uint32_t recent;
874 uint32_t unseen;
875 int r;
876
877 r = mboxdriver_cached_status_folder(session, mb, &messages, &recent, &unseen);
878 if (r != MAIL_NO_ERROR)
879 return r;
880
881 * result = recent;
882
883 return MAIL_NO_ERROR;
884}
885
886static int mboxdriver_cached_unseen_number(mailsession * session, char * mb,
887 uint32_t * result)
888{
889 uint32_t messages;
890 uint32_t recent;
891 uint32_t unseen;
892 int r;
893
894 r = mboxdriver_cached_status_folder(session, mb,
895 &messages, &recent, &unseen);
896 if (r != MAIL_NO_ERROR)
897 return r;
898
899 * result = unseen;
900
901 return MAIL_NO_ERROR;
902}
903
904/* messages operations */
905
906static int mboxdriver_cached_append_message(mailsession * session,
907 char * message, size_t size)
908{
909 return mailsession_append_message(get_ancestor(session), message, size);
910}
911
912static int
913mboxdriver_cached_get_messages_list(mailsession * session,
914 struct mailmessage_list ** result)
915{
916 struct mailmbox_folder * folder;
917 int res;
918
919 folder = get_mbox_session(session);
920 if (folder == NULL) {
921 res = MAIL_ERROR_BAD_STATE;
922 goto err;
923 }
924
925 return mbox_get_uid_messages_list(folder,
926 session, mbox_cached_message_driver, result);
927
928 err:
929 return res;
930}
931
932static int
933get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
934 mailsession * session, uint32_t num,
935 struct mailimf_fields ** result)
936{
937 int r;
938 char keyname[PATH_MAX];
939 struct mailimf_fields * fields;
940 int res;
941 struct mailmbox_msg_info * info;
942 struct mailmbox_folder * folder;
943 chashdatum key;
944 chashdatum data;
945
946 folder = get_mbox_session(session);
947 if (folder == NULL) {
948 res = MAIL_ERROR_BAD_STATE;
949 goto err;
950 }
951
952 key.data = &num;
953 key.len = sizeof(num);
954
955 r = chash_get(folder->mb_hash, &key, &data);
956 if (r < 0) {
957 res = MAIL_ERROR_MSG_NOT_FOUND;
958 goto err;
959 }
960
961 info = data.data;
962
963 snprintf(keyname, PATH_MAX, "%u-%u-envelope", num, info->msg_body_len);
964
965 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields);
966 if (r != MAIL_NO_ERROR) {
967 res = r;
968 goto err;
969 }
970
971 * result = fields;
972
973 return MAIL_NO_ERROR;
974
975 err:
976 return res;
977}
978
979static int
980write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
981 mailsession * session, uint32_t num,
982 struct mailimf_fields * fields)
983{
984 int r;
985 char keyname[PATH_MAX];
986 int res;
987 struct mailmbox_msg_info * info;
988 struct mailmbox_folder * folder;
989 chashdatum key;
990 chashdatum data;
991
992 folder = get_mbox_session(session);
993 if (folder == NULL) {
994 res = MAIL_ERROR_BAD_STATE;
995 goto err;
996 }
997
998 key.data = &num;
999 key.len = sizeof(num);
1000
1001 r = chash_get(folder->mb_hash, &key, &data);
1002 if (r < 0) {
1003 res = MAIL_ERROR_MSG_NOT_FOUND;
1004 goto err;
1005 }
1006
1007 info = data.data;
1008
1009 snprintf(keyname, PATH_MAX, "%u-%u-envelope", num, info->msg_body_len);
1010
1011 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields);
1012 if (r != MAIL_NO_ERROR) {
1013 res = r;
1014 goto err;
1015 }
1016
1017 return MAIL_NO_ERROR;
1018
1019 err:
1020 return res;
1021}
1022
1023static int
1024mboxdriver_cached_get_envelopes_list(mailsession * session,
1025 struct mailmessage_list * env_list)
1026{
1027 int r;
1028 unsigned int i;
1029 struct mbox_cached_session_state_data * cached_data;
1030 char filename_env[PATH_MAX];
1031 char filename_flags[PATH_MAX];
1032 struct mail_cache_db * cache_db_env;
1033 struct mail_cache_db * cache_db_flags;
1034 MMAPString * mmapstr;
1035 int res;
1036 struct mailmbox_folder * folder;
1037
1038 folder = get_mbox_session(session);
1039 if (folder == NULL) {
1040 res = MAIL_ERROR_BAD_STATE;
1041 goto err;
1042 }
1043
1044 cached_data = get_cached_data(session);
1045 if (cached_data->mbox_quoted_mb == NULL) {
1046 res = MAIL_ERROR_BAD_STATE;
1047 goto err;
1048 }
1049
1050 mbox_flags_store_process(cached_data->mbox_flags_directory,
1051 cached_data->mbox_quoted_mb,
1052 cached_data->mbox_flags_store);
1053
1054 mmapstr = mmap_string_new("");
1055 if (mmapstr == NULL) {
1056 res = MAIL_ERROR_MEMORY;
1057 goto err;
1058 }
1059
1060 snprintf(filename_env, PATH_MAX, "%s%c%s%c%s",
1061 cached_data->mbox_cache_directory, MAIL_DIR_SEPARATOR,
1062 cached_data->mbox_quoted_mb,
1063 MAIL_DIR_SEPARATOR, ENV_NAME);
1064
1065 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
1066 if (r < 0) {
1067 res = MAIL_ERROR_MEMORY;
1068 goto free_mmapstr;
1069 }
1070
1071 snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s",
1072 cached_data->mbox_flags_directory, MAIL_DIR_SEPARATOR,
1073 cached_data->mbox_quoted_mb,
1074 MAIL_DIR_SEPARATOR, FLAGS_NAME);
1075
1076 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
1077 if (r < 0) {
1078 res = MAIL_ERROR_FILE;
1079 goto close_db_env;
1080 }
1081
1082 /* fill with cached */
1083
1084 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1085 mailmessage * msg;
1086 struct mailimf_fields * fields;
1087 struct mail_flags * flags;
1088
1089 msg = carray_get(env_list->msg_tab, i);
1090
1091 if (msg->msg_fields == NULL) {
1092 r = get_cached_envelope(cache_db_env, mmapstr, session,
1093 msg->msg_index, &fields);
1094 if (r == MAIL_NO_ERROR) {
1095 msg->msg_cached = TRUE;
1096 msg->msg_fields = fields;
1097 }
1098 }
1099
1100 if (msg->msg_flags == NULL) {
1101 r = mboxdriver_get_cached_flags(cache_db_flags, mmapstr,
1102 session, msg->msg_index,
1103 &flags);
1104 if (r == MAIL_NO_ERROR) {
1105 msg->msg_flags = flags;
1106 }
1107 }
1108 }
1109
1110 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
1111 mail_cache_db_close_unlock(filename_env, cache_db_env);
1112
1113 r = mailsession_get_envelopes_list(get_ancestor(session), env_list);
1114
1115 if (r != MAIL_NO_ERROR) {
1116 res = r;
1117 goto free_mmapstr;
1118 }
1119
1120 /* add flags */
1121
1122 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1123 mailmessage * msg;
1124
1125 msg = carray_get(env_list->msg_tab, i);
1126
1127 if (msg->msg_flags == NULL)
1128 msg->msg_flags = mail_flags_new_empty();
1129 }
1130
1131 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
1132 if (r < 0) {
1133 res = MAIL_ERROR_MEMORY;
1134 goto free_mmapstr;
1135 }
1136
1137 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
1138 if (r < 0) {
1139 res = MAIL_ERROR_FILE;
1140 goto close_db_env;
1141 }
1142
1143 /* must write cache */
1144
1145 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1146 mailmessage * msg;
1147
1148 msg = carray_get(env_list->msg_tab, i);
1149
1150 if (msg->msg_fields != NULL) {
1151 if (!msg->msg_cached) {
1152 /* msg->msg_index is the numerical UID of the message */
1153 r = write_cached_envelope(cache_db_env, mmapstr,
1154 session, msg->msg_index, msg->msg_fields);
1155 }
1156 }
1157
1158 if (msg->msg_flags != NULL) {
1159 r = mboxdriver_write_cached_flags(cache_db_flags, mmapstr,
1160 msg->msg_uid, msg->msg_flags);
1161 }
1162 }
1163
1164 /* flush cache */
1165
1166 maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list);
1167
1168 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
1169 mail_cache_db_close_unlock(filename_env, cache_db_env);
1170
1171 mmap_string_free(mmapstr);
1172
1173 return MAIL_NO_ERROR;
1174
1175 close_db_env:
1176 mail_cache_db_close_unlock(filename_env, cache_db_env);
1177 free_mmapstr:
1178 mmap_string_free(mmapstr);
1179 err:
1180 return res;
1181}
1182
1183
1184static int
1185mboxdriver_cached_remove_message(mailsession * session, uint32_t num)
1186{
1187 return mailsession_remove_message(get_ancestor(session), num);
1188}
1189
1190static int mboxdriver_cached_get_message(mailsession * session,
1191 uint32_t num, mailmessage ** result)
1192{
1193 mailmessage * msg_info;
1194 int r;
1195
1196 msg_info = mailmessage_new();
1197 if (msg_info == NULL)
1198 return MAIL_ERROR_MEMORY;
1199
1200 r = mailmessage_init(msg_info, session, mbox_cached_message_driver, num, 0);
1201 if (r != MAIL_NO_ERROR) {
1202 mailmessage_free(msg_info);
1203 return r;
1204 }
1205
1206 * result = msg_info;
1207
1208 return MAIL_NO_ERROR;
1209}
1210
1211static int mboxdriver_cached_get_message_by_uid(mailsession * session,
1212 const char * uid,
1213 mailmessage ** result)
1214{
1215 uint32_t num;
1216 char * p;
1217 chashdatum key;
1218 chashdatum data;
1219 struct mailmbox_msg_info * info;
1220 struct mailmbox_folder * folder;
1221 int r;
1222
1223 if (uid == NULL)
1224 return MAIL_ERROR_INVAL;
1225
1226 num = strtoul(uid, &p, 10);
1227 if (p == uid || * p != '-')
1228 return MAIL_ERROR_INVAL;
1229
1230 folder = get_mbox_session(session);
1231 if (folder == NULL)
1232 return MAIL_ERROR_BAD_STATE;
1233
1234 key.data = &num;
1235 key.len = sizeof(num);
1236
1237 r = chash_get(folder->mb_hash, &key, &data);
1238 if (r == 0) {
1239 char * body_len_p = p + 1;
1240 size_t body_len;
1241
1242 info = data.data;
1243 /* Check if the cached message has the same UID */
1244 body_len = strtoul(body_len_p, &p, 10);
1245 if (p == body_len_p || * p != '\0')
1246 return MAIL_ERROR_INVAL;
1247
1248 if (body_len == info->msg_body_len)
1249 return mboxdriver_cached_get_message(session, num, result);
1250 }
1251
1252 return MAIL_ERROR_MSG_NOT_FOUND;
1253}
diff --git a/kmicromail/libetpan/generic/mboxdriver_cached.h b/kmicromail/libetpan/generic/mboxdriver_cached.h
new file mode 100644
index 0000000..b0d8dbf
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_cached.h
@@ -0,0 +1,54 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MBOXDRIVER_CACHED_H
37
38#define MBOXDRIVER_CACHED_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/mboxdriver_types.h>
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48extern mailsession_driver * mbox_cached_session_driver;
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/kmicromail/libetpan/generic/mboxdriver_cached_message.c b/kmicromail/libetpan/generic/mboxdriver_cached_message.c
new file mode 100644
index 0000000..6d92b22
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_cached_message.c
@@ -0,0 +1,360 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mboxdriver_cached_message.h"
37
38#include "mailmessage_tools.h"
39#include "mboxdriver_tools.h"
40#include "mboxdriver_cached.h"
41#include "mboxdriver.h"
42#include "mailmbox.h"
43#include "mail_cache_db.h"
44#include "generic_cache.h"
45
46#include <unistd.h>
47#include <sys/mman.h>
48#include <sys/types.h>
49#include <sys/stat.h>
50#include <fcntl.h>
51#include <string.h>
52#include <stdlib.h>
53
54static int mbox_prefetch(mailmessage * msg_info);
55
56static void mbox_prefetch_free(struct generic_message_t * msg);
57
58static int mbox_initialize(mailmessage * msg_info);
59
60static void mbox_uninitialize(mailmessage * msg_info);
61
62static void mbox_flush(mailmessage * msg_info);
63
64static void mbox_check(mailmessage * msg_info);
65
66static int mbox_fetch_size(mailmessage * msg_info,
67 size_t * result);
68
69static int mbox_get_flags(mailmessage * msg_info,
70 struct mail_flags ** result);
71
72static int mbox_fetch_header(mailmessage * msg_info,
73 char ** result,
74 size_t * result_len);
75
76static mailmessage_driver local_mbox_cached_message_driver = {
77 .msg_name = "mbox-cached",
78
79 .msg_initialize = mbox_initialize,
80 .msg_uninitialize = mbox_uninitialize,
81
82 .msg_flush = mbox_flush,
83 .msg_check = mbox_check,
84
85 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
86
87 .msg_fetch = mailmessage_generic_fetch,
88 .msg_fetch_header = mbox_fetch_header,
89 .msg_fetch_body = mailmessage_generic_fetch_body,
90 .msg_fetch_size = mbox_fetch_size,
91 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
92 .msg_fetch_section = mailmessage_generic_fetch_section,
93 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
94 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
95 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
96 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
97
98 .msg_get_flags = mbox_get_flags,
99};
100
101mailmessage_driver * mbox_cached_message_driver =
102&local_mbox_cached_message_driver;
103
104static inline struct mbox_cached_session_state_data *
105get_cached_session_data(mailmessage * msg)
106{
107 return msg->msg_session->sess_data;
108}
109
110static inline mailsession * get_ancestor_session(mailmessage * msg)
111{
112 return get_cached_session_data(msg)->mbox_ancestor;
113}
114
115static inline struct mbox_session_state_data *
116get_ancestor_session_data(mailmessage * msg)
117{
118 return get_ancestor_session(msg)->sess_data;
119}
120
121static inline struct mailmbox_folder *
122get_mbox_session(mailmessage * msg)
123{
124 return get_ancestor_session_data(msg)->mbox_folder;
125}
126
127static int mbox_prefetch(mailmessage * msg_info)
128{
129 struct generic_message_t * msg;
130 int r;
131 char * msg_content;
132 size_t msg_length;
133
134 r = mboxdriver_fetch_msg(get_ancestor_session(msg_info),
135 msg_info->msg_index,
136 &msg_content, &msg_length);
137 if (r != MAIL_NO_ERROR)
138 return r;
139
140 msg = msg_info->msg_data;
141
142 msg->msg_message = msg_content;
143 msg->msg_length = msg_length;
144
145 return MAIL_NO_ERROR;
146}
147
148static void mbox_prefetch_free(struct generic_message_t * msg)
149{
150 if (msg->msg_message != NULL) {
151 mmap_string_unref(msg->msg_message);
152 msg->msg_message = NULL;
153 }
154}
155
156static int mbox_initialize(mailmessage * msg_info)
157{
158 struct generic_message_t * msg;
159 int r;
160 char * uid;
161 char static_uid[PATH_MAX];
162 struct mailmbox_msg_info * info;
163 struct mailmbox_folder * folder;
164 int res;
165 chashdatum key;
166 chashdatum data;
167
168 folder = get_mbox_session(msg_info);
169 if (folder == NULL) {
170 res = MAIL_ERROR_BAD_STATE;
171 goto err;
172 }
173
174 key.data = (char *) &msg_info->msg_index;
175 key.len = sizeof(msg_info->msg_index);
176
177 r = chash_get(folder->mb_hash, &key, &data);
178 if (r < 0) {
179 res = MAIL_ERROR_MSG_NOT_FOUND;
180 goto err;
181 }
182
183 info = (struct mailmbox_msg_info *) data.data;
184
185 snprintf(static_uid, PATH_MAX, "%u-%u", msg_info->msg_index, info->msg_body_len);
186 uid = strdup(static_uid);
187 if (uid == NULL) {
188 res = MAIL_ERROR_MEMORY;
189 goto err;
190 }
191
192 r = mailmessage_generic_initialize(msg_info);
193 if (r != MAIL_NO_ERROR) {
194 free(uid);
195 res = r;
196 goto err;
197 }
198
199 msg = msg_info->msg_data;
200
201 msg->msg_prefetch = mbox_prefetch;
202 msg->msg_prefetch_free = mbox_prefetch_free;
203 msg_info->msg_uid = uid;
204
205 return MAIL_NO_ERROR;
206
207 err:
208 return res;
209}
210
211static void mbox_uninitialize(mailmessage * msg_info)
212{
213 mailmessage_generic_uninitialize(msg_info);
214}
215
216#define FLAGS_NAME "flags.db"
217
218static void mbox_flush(mailmessage * msg_info)
219{
220 mailmessage_generic_flush(msg_info);
221}
222
223static void mbox_check(mailmessage * msg_info)
224{
225 int r;
226
227 if (msg_info->msg_flags != NULL) {
228 r = mail_flags_store_set(get_cached_session_data(msg_info)->mbox_flags_store,
229 msg_info);
230 /* ignore errors */
231 }
232}
233
234
235static int mbox_fetch_size(mailmessage * msg_info,
236 size_t * result)
237{
238 int r;
239 size_t size;
240
241 r = mboxdriver_fetch_size(get_ancestor_session(msg_info),
242 msg_info->msg_index, &size);
243 if (r != MAIL_NO_ERROR)
244 return r;
245
246 * result = size;
247
248 return MAIL_NO_ERROR;
249}
250
251static int mbox_get_flags(mailmessage * msg_info,
252 struct mail_flags ** result)
253{
254 int r;
255 struct mail_flags * flags;
256 struct mail_cache_db * cache_db_flags;
257 char filename_flags[PATH_MAX];
258 int res;
259 struct mbox_cached_session_state_data * cached_data;
260 MMAPString * mmapstr;
261 struct mailmbox_folder * folder;
262
263 if (msg_info->msg_flags != NULL) {
264 * result = msg_info->msg_flags;
265
266 return MAIL_NO_ERROR;
267 }
268
269 flags = mail_flags_store_get(get_cached_session_data(msg_info)->mbox_flags_store,
270 msg_info->msg_index);
271
272 if (flags == NULL) {
273 folder = get_mbox_session(msg_info);
274 if (folder == NULL) {
275 res = MAIL_ERROR_BAD_STATE;
276 goto err;
277 }
278
279 cached_data = get_cached_session_data(msg_info);
280 if (cached_data->mbox_quoted_mb == NULL) {
281 res = MAIL_ERROR_BAD_STATE;
282 goto err;
283 }
284
285 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
286 cached_data->mbox_flags_directory,
287 cached_data->mbox_quoted_mb, FLAGS_NAME);
288
289 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
290 if (r < 0) {
291 res = MAIL_ERROR_MEMORY;
292 goto err;
293 }
294
295 mmapstr = mmap_string_new("");
296 if (mmapstr == NULL) {
297 res = MAIL_ERROR_MEMORY;
298 goto close_db_flags;
299 }
300
301 if (msg_info->msg_index > folder->mb_written_uid) {
302 flags = mail_flags_new_empty();
303 }
304 else {
305 r = mboxdriver_get_cached_flags(cache_db_flags, mmapstr,
306 msg_info->msg_session,
307 msg_info->msg_index, &flags);
308 if (r != MAIL_NO_ERROR) {
309 flags = mail_flags_new_empty();
310 if (flags == NULL) {
311 res = MAIL_ERROR_MEMORY;
312 goto free_mmapstr;
313 }
314 }
315 }
316
317 mmap_string_free(mmapstr);
318 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
319 }
320
321 msg_info->msg_flags = flags;
322
323 * result = flags;
324
325 return MAIL_NO_ERROR;
326
327 free_mmapstr:
328 mmap_string_free(mmapstr);
329 close_db_flags:
330 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
331 err:
332 return res;
333}
334
335static int mbox_fetch_header(mailmessage * msg_info,
336 char ** result,
337 size_t * result_len)
338{
339 struct generic_message_t * msg;
340 int r;
341 char * msg_content;
342 size_t msg_length;
343
344 msg = msg_info->msg_data;
345 if (msg->msg_message != NULL) {
346 return mailmessage_generic_fetch_header(msg_info, result, result_len);
347 }
348 else {
349 r = mboxdriver_fetch_header(get_ancestor_session(msg_info),
350 msg_info->msg_index,
351 &msg_content, &msg_length);
352 if (r != MAIL_NO_ERROR)
353 return r;
354
355 * result = msg_content;
356 * result_len = msg_length;
357
358 return MAIL_NO_ERROR;
359 }
360}
diff --git a/kmicromail/libetpan/generic/mboxdriver_cached_message.h b/kmicromail/libetpan/generic/mboxdriver_cached_message.h
new file mode 100644
index 0000000..a6673b3
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_cached_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MBOXDRIVER_CACHED_MESSAGE_H
37
38#define MBOXDRIVER_CACHED_MESSAGE_H
39
40#include <libetpan/mailmessage.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * mbox_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/mboxdriver_message.c b/kmicromail/libetpan/generic/mboxdriver_message.c
new file mode 100644
index 0000000..da9a65d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_message.c
@@ -0,0 +1,225 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mhdriver_message.h"
37
38#include "mailmessage_tools.h"
39#include "mboxdriver_tools.h"
40#include "mboxdriver.h"
41#include "mailmbox.h"
42
43#include <unistd.h>
44#include <sys/mman.h>
45#include <sys/types.h>
46#include <sys/stat.h>
47#include <fcntl.h>
48#include <string.h>
49#include <stdlib.h>
50
51static int mbox_prefetch(mailmessage * msg_info);
52
53static void mbox_prefetch_free(struct generic_message_t * msg);
54
55static int mbox_initialize(mailmessage * msg_info);
56
57static int mbox_fetch_size(mailmessage * msg_info,
58 size_t * result);
59
60static int mbox_fetch_header(mailmessage * msg_info,
61 char ** result,
62 size_t * result_len);
63
64static mailmessage_driver local_mbox_message_driver = {
65 .msg_name = "mbox",
66
67 .msg_initialize = mbox_initialize,
68 .msg_uninitialize = mailmessage_generic_uninitialize,
69
70 .msg_flush = mailmessage_generic_flush,
71 .msg_check = NULL,
72
73 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
74
75 .msg_fetch = mailmessage_generic_fetch,
76 .msg_fetch_header = mbox_fetch_header,
77 .msg_fetch_body = mailmessage_generic_fetch_body,
78 .msg_fetch_size = mbox_fetch_size,
79 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
80 .msg_fetch_section = mailmessage_generic_fetch_section,
81 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
82 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
83 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
84 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
85
86 .msg_get_flags = NULL,
87};
88
89mailmessage_driver * mbox_message_driver = &local_mbox_message_driver;
90
91static inline struct mbox_session_state_data * get_data(mailmessage * msg)
92{
93 return msg->msg_session->sess_data;
94}
95
96static inline struct mailmbox_folder * get_mbox_session(mailmessage * msg)
97{
98 return get_data(msg)->mbox_folder;
99}
100
101
102static int mbox_prefetch(mailmessage * msg_info)
103{
104 struct generic_message_t * msg;
105 int r;
106 char * msg_content;
107 size_t msg_length;
108
109 r = mboxdriver_fetch_msg(msg_info->msg_session, msg_info->msg_index,
110 &msg_content, &msg_length);
111 if (r != MAIL_NO_ERROR)
112 return r;
113
114 msg = msg_info->msg_data;
115
116 msg->msg_message = msg_content;
117 msg->msg_length = msg_length;
118
119 return MAIL_NO_ERROR;
120}
121
122static void mbox_prefetch_free(struct generic_message_t * msg)
123{
124 if (msg->msg_message != NULL) {
125 mmap_string_unref(msg->msg_message);
126 msg->msg_message = NULL;
127 }
128}
129
130static int mbox_initialize(mailmessage * msg_info)
131{
132 struct generic_message_t * msg;
133 int r;
134 char * uid;
135 char static_uid[PATH_MAX];
136 struct mailmbox_msg_info * info;
137 struct mailmbox_folder * folder;
138 int res;
139 chashdatum key;
140 chashdatum data;
141
142 folder = get_mbox_session(msg_info);
143 if (folder == NULL) {
144 res = MAIL_ERROR_BAD_STATE;
145 goto err;
146 }
147
148 key.data = &msg_info->msg_index;
149 key.len = sizeof(msg_info->msg_index);
150
151 r = chash_get(folder->mb_hash, &key, &data);
152 if (r < 0) {
153 res = MAIL_ERROR_MSG_NOT_FOUND;
154 goto err;
155 }
156
157 info = data.data;
158
159 snprintf(static_uid, PATH_MAX, "%u-%u",
160 msg_info->msg_index, info->msg_body_len);
161 uid = strdup(static_uid);
162 if (uid == NULL) {
163 res = MAIL_ERROR_MEMORY;
164 goto err;
165 }
166
167 r = mailmessage_generic_initialize(msg_info);
168 if (r != MAIL_NO_ERROR) {
169 free(uid);
170 res = r;
171 goto err;
172 }
173
174 msg = msg_info->msg_data;
175 msg->msg_prefetch = mbox_prefetch;
176 msg->msg_prefetch_free = mbox_prefetch_free;
177 msg_info->msg_uid = uid;
178
179 return MAIL_NO_ERROR;
180
181 err:
182 return res;
183}
184
185static int mbox_fetch_size(mailmessage * msg_info,
186 size_t * result)
187{
188 int r;
189 size_t size;
190
191 r = mboxdriver_fetch_size(msg_info->msg_session,
192 msg_info->msg_index, &size);
193 if (r != MAIL_NO_ERROR)
194 return r;
195
196 * result = size;
197
198 return MAIL_NO_ERROR;
199}
200
201static int mbox_fetch_header(mailmessage * msg_info,
202 char ** result,
203 size_t * result_len)
204{
205 struct generic_message_t * msg;
206 int r;
207 char * msg_content;
208 size_t msg_length;
209
210 msg = msg_info->msg_data;
211 if (msg->msg_message != NULL) {
212 return mailmessage_generic_fetch_header(msg_info, result, result_len);
213 }
214 else {
215 r = mboxdriver_fetch_header(msg_info->msg_session, msg_info->msg_index,
216 &msg_content, &msg_length);
217 if (r != MAIL_NO_ERROR)
218 return r;
219
220 * result = msg_content;
221 * result_len = msg_length;
222
223 return MAIL_NO_ERROR;
224 }
225}
diff --git a/kmicromail/libetpan/generic/mboxdriver_message.h b/kmicromail/libetpan/generic/mboxdriver_message.h
new file mode 100644
index 0000000..cdabd23
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MBOXDRIVER_MESSAGE_H
37
38#define MBOXDRIVER_MESSAGE_H
39
40#include <libetpan/mboxdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * mbox_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/mboxdriver_tools.c b/kmicromail/libetpan/generic/mboxdriver_tools.c
new file mode 100644
index 0000000..1e27798
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_tools.c
@@ -0,0 +1,434 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mboxdriver_tools.h"
37
38#include <sys/types.h>
39#include <sys/stat.h>
40#include <fcntl.h>
41#include <unistd.h>
42
43#include "maildriver_types.h"
44#include "mailmbox.h"
45#include "mboxdriver_cached.h"
46#include "mboxdriver.h"
47#include "generic_cache.h"
48#include "mailmessage.h"
49#include "imfcache.h"
50#include "mail_cache_db.h"
51
52static inline struct mbox_session_state_data *
53session_get_data(mailsession * session)
54{
55 return session->sess_data;
56}
57
58static inline struct mailmbox_folder *
59session_get_mbox_session(mailsession * session)
60{
61 return session_get_data(session)->mbox_folder;
62}
63
64static inline struct mbox_cached_session_state_data *
65cached_session_get_data(mailsession * session)
66{
67 return session->sess_data;
68}
69
70static inline mailsession *
71cached_session_get_ancestor(mailsession * session)
72{
73 return cached_session_get_data(session)->mbox_ancestor;
74}
75
76static inline struct mbox_session_state_data *
77cached_session_get_ancestor_data(mailsession * session)
78{
79 return cached_session_get_ancestor(session)->sess_data;
80}
81
82static inline struct mailmbox_folder *
83cached_session_get_mbox_session(mailsession * session)
84{
85 return session_get_mbox_session(cached_session_get_ancestor(session));
86}
87
88
89int mboxdriver_mbox_error_to_mail_error(int error)
90{
91 switch (error) {
92 case MAILMBOX_NO_ERROR:
93 return MAIL_NO_ERROR;
94
95 case MAILMBOX_ERROR_PARSE:
96 return MAIL_ERROR_PARSE;
97
98 case MAILMBOX_ERROR_INVAL:
99 return MAIL_ERROR_INVAL;
100
101 case MAILMBOX_ERROR_FILE_NOT_FOUND:
102 return MAIL_ERROR_PARSE;
103
104 case MAILMBOX_ERROR_MEMORY:
105 return MAIL_ERROR_MEMORY;
106
107 case MAILMBOX_ERROR_TEMPORARY_FILE:
108 return MAIL_ERROR_PARSE;
109
110 case MAILMBOX_ERROR_FILE:
111 return MAIL_ERROR_FILE;
112
113 case MAILMBOX_ERROR_MSG_NOT_FOUND:
114 return MAIL_ERROR_MSG_NOT_FOUND;
115
116 case MAILMBOX_ERROR_READONLY:
117 return MAIL_ERROR_READONLY;
118
119 default:
120 return MAIL_ERROR_INVAL;
121 }
122}
123
124int mboxdriver_fetch_msg(mailsession * session, uint32_t index,
125 char ** result, size_t * result_len)
126{
127 int r;
128 char * msg_content;
129 size_t msg_length;
130 struct mailmbox_folder * folder;
131
132 folder = session_get_mbox_session(session);
133 if (folder == NULL)
134 return MAIL_ERROR_BAD_STATE;
135
136 r = mailmbox_fetch_msg(folder, index, &msg_content, &msg_length);
137 if (r != MAILMBOX_NO_ERROR)
138 return mboxdriver_mbox_error_to_mail_error(r);
139
140 * result = msg_content;
141 * result_len = msg_length;
142
143 return MAIL_NO_ERROR;
144}
145
146
147int mboxdriver_fetch_size(mailsession * session, uint32_t index,
148 size_t * result)
149{
150 struct mailmbox_folder * folder;
151 int r;
152 char * data;
153 size_t len;
154 int res;
155
156 folder = session_get_mbox_session(session);
157 if (folder == NULL) {
158 res = MAIL_ERROR_FETCH;
159 goto err;
160 }
161
162 r = mailmbox_validate_read_lock(folder);
163 if (r != MAILMBOX_NO_ERROR) {
164 res = mboxdriver_mbox_error_to_mail_error(r);
165 goto err;
166 }
167
168 r = mailmbox_fetch_msg_no_lock(folder, index, &data, &len);
169 if (r != MAILMBOX_NO_ERROR) {
170 res = mboxdriver_mbox_error_to_mail_error(r);
171 goto unlock;
172 }
173
174 mailmbox_read_unlock(folder);
175
176 * result = len;
177
178 return MAIL_NO_ERROR;
179
180 unlock:
181 mailmbox_read_unlock(folder);
182 err:
183 return res;
184}
185
186
187int
188mboxdriver_get_cached_flags(struct mail_cache_db * cache_db,
189 MMAPString * mmapstr,
190 mailsession * session,
191 uint32_t num,
192 struct mail_flags ** result)
193{
194 int r;
195 char keyname[PATH_MAX];
196 struct mail_flags * flags;
197 int res;
198 struct mailmbox_msg_info * info;
199 struct mailmbox_folder * folder;
200 chashdatum key;
201 chashdatum data;
202
203 folder = cached_session_get_mbox_session(session);
204 if (folder == NULL) {
205 res = MAIL_ERROR_BAD_STATE;
206 goto err;
207 }
208
209 key.data = &num;
210 key.len = sizeof(num);
211
212 r = chash_get(folder->mb_hash, &key, &data);
213 if (r < 0) {
214 res = MAIL_ERROR_MSG_NOT_FOUND;
215 goto err;
216 }
217
218 info = data.data;
219
220 snprintf(keyname, PATH_MAX, "%u-%u-flags", num, info->msg_body_len);
221
222 r = generic_cache_flags_read(cache_db, mmapstr, keyname, &flags);
223 if (r != MAIL_NO_ERROR) {
224 res = r;
225 goto err;
226 }
227
228 * result = flags;
229
230 return MAIL_NO_ERROR;
231
232 err:
233 return res;
234}
235
236int
237mboxdriver_write_cached_flags(struct mail_cache_db * cache_db,
238 MMAPString * mmapstr,
239 char * uid,
240 struct mail_flags * flags)
241{
242 int r;
243 char keyname[PATH_MAX];
244 int res;
245
246 snprintf(keyname, PATH_MAX, "%s-flags", uid);
247
248 r = generic_cache_flags_write(cache_db, mmapstr, keyname, flags);
249 if (r != MAIL_NO_ERROR) {
250 res = r;
251 goto err;
252 }
253
254 return MAIL_NO_ERROR;
255
256 err:
257 return res;
258}
259
260
261int mboxdriver_fetch_header(mailsession * session, uint32_t index,
262 char ** result, size_t * result_len)
263{
264 int r;
265 char * msg_content;
266 size_t msg_length;
267 struct mailmbox_folder * folder;
268
269 folder = session_get_mbox_session(session);
270 if (folder == NULL)
271 return MAIL_ERROR_BAD_STATE;
272
273 r = mailmbox_fetch_msg_headers(folder, index, &msg_content, &msg_length);
274 if (r != MAILMBOX_NO_ERROR)
275 return mboxdriver_mbox_error_to_mail_error(r);
276
277 * result = msg_content;
278 * result_len = msg_length;
279
280 return MAIL_NO_ERROR;
281}
282
283int mbox_get_locked_messages_list(struct mailmbox_folder * folder,
284 mailsession * session,
285 mailmessage_driver * driver,
286 int (* lock)(struct mailmbox_folder *),
287 int (* unlock)(struct mailmbox_folder *),
288 struct mailmessage_list ** result)
289{
290 struct mailmessage_list * env_list;
291 unsigned int i;
292 int r;
293 int res;
294 carray * tab;
295
296 tab = carray_new(128);
297 if (tab == NULL) {
298 res = MAIL_ERROR_MEMORY;
299 goto err;
300 }
301
302 r = lock(folder);
303 if (r != MAIL_NO_ERROR) {
304 res = r;
305 goto free;
306 }
307
308 for(i = 0 ; i < carray_count(folder->mb_tab) ; i ++) {
309 struct mailmbox_msg_info * msg_info;
310 mailmessage * msg;
311
312 msg_info = carray_get(folder->mb_tab, i);
313 if (msg_info == NULL)
314 continue;
315
316 if (msg_info->msg_deleted)
317 continue;
318
319 msg = mailmessage_new();
320 if (msg == NULL) {
321 res = MAIL_ERROR_MEMORY;
322 goto unlock;
323 }
324
325 r = mailmessage_init(msg, session, driver, msg_info->msg_uid,
326 msg_info->msg_size - msg_info->msg_start_len);
327 if (r != MAIL_NO_ERROR) {
328 res = r;
329 goto unlock;
330 }
331
332 r = carray_add(tab, msg, NULL);
333 if (r < 0) {
334 mailmessage_free(msg);
335 res = MAIL_ERROR_MEMORY;
336 goto unlock;
337 }
338 }
339
340 env_list = mailmessage_list_new(tab);
341 if (env_list == NULL) {
342 res = MAIL_ERROR_MEMORY;
343 goto unlock;
344 }
345
346 unlock(folder);
347
348 * result = env_list;
349
350 return MAIL_NO_ERROR;
351
352 unlock:
353 unlock(folder);
354 free:
355 for(i = 0 ; i < carray_count(tab) ; i ++)
356 mailmessage_free(carray_get(tab, i));
357 carray_free(tab);
358 err:
359 return res;
360}
361
362static int release_read_mbox(struct mailmbox_folder * folder)
363{
364 int r;
365
366 r = mailmbox_read_unlock(folder);
367 return mboxdriver_mbox_error_to_mail_error(r);
368}
369
370static int acquire_read_mbox(struct mailmbox_folder * folder)
371{
372 int r;
373
374 r = mailmbox_validate_read_lock(folder);
375 return mboxdriver_mbox_error_to_mail_error(r);
376}
377
378static int release_write_mbox(struct mailmbox_folder * folder)
379{
380 int r;
381
382 r = mailmbox_write_unlock(folder);
383 return mboxdriver_mbox_error_to_mail_error(r);
384}
385
386static int acquire_write_mbox(struct mailmbox_folder * folder)
387{
388 int r;
389 int res;
390
391 r = mailmbox_validate_write_lock(folder);
392 if (r != MAILMBOX_NO_ERROR) {
393 res = mboxdriver_mbox_error_to_mail_error(r);
394 goto err;
395 }
396
397 if (folder->mb_written_uid < folder->mb_max_uid) {
398 r = mailmbox_expunge_no_lock(folder);
399 if (r != MAILMBOX_NO_ERROR) {
400 res = mboxdriver_mbox_error_to_mail_error(r);
401 goto unlock;
402 }
403 }
404
405 return MAIL_NO_ERROR;
406
407 unlock:
408 mailmbox_write_unlock(folder);
409 err:
410 return res;
411}
412
413/* get message list with all valid written UID */
414
415int mbox_get_uid_messages_list(struct mailmbox_folder * folder,
416 mailsession * session,
417 mailmessage_driver * driver,
418 struct mailmessage_list ** result)
419{
420 return mbox_get_locked_messages_list(folder, session, driver,
421 acquire_write_mbox, release_write_mbox, result);
422}
423
424
425/* get message list */
426
427int mbox_get_messages_list(struct mailmbox_folder * folder,
428 mailsession * session,
429 mailmessage_driver * driver,
430 struct mailmessage_list ** result)
431{
432 return mbox_get_locked_messages_list(folder, session, driver,
433 acquire_read_mbox, release_read_mbox, result);
434}
diff --git a/kmicromail/libetpan/generic/mboxdriver_tools.h b/kmicromail/libetpan/generic/mboxdriver_tools.h
new file mode 100644
index 0000000..3ec82ec
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_tools.h
@@ -0,0 +1,85 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MBOXDRIVER_TOOLS_H
37
38#define MBOXDRIVER_TOOLS_H
39
40#include "mail_cache_db_types.h"
41#include "mboxdriver_types.h"
42#include "mailmbox.h"
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48int mboxdriver_mbox_error_to_mail_error(int error);
49
50int mboxdriver_fetch_msg(mailsession * session, uint32_t index,
51 char ** result, size_t * result_len);
52
53int mboxdriver_fetch_size(mailsession * session, uint32_t index,
54 size_t * result);
55
56int
57mboxdriver_get_cached_flags(struct mail_cache_db * cache_db,
58 MMAPString * mmapstr,
59 mailsession * session,
60 uint32_t num,
61 struct mail_flags ** result);
62
63int
64mboxdriver_write_cached_flags(struct mail_cache_db * cache_db,
65 MMAPString * mmapstr,
66 char * uid, struct mail_flags * flags);
67
68int mbox_get_uid_messages_list(struct mailmbox_folder * folder,
69 mailsession * session,
70 mailmessage_driver * driver,
71 struct mailmessage_list ** result);
72
73int mbox_get_messages_list(struct mailmbox_folder * folder,
74 mailsession * session,
75 mailmessage_driver * driver,
76 struct mailmessage_list ** result);
77
78int mboxdriver_fetch_header(mailsession * session, uint32_t index,
79 char ** result, size_t * result_len);
80
81#ifdef __cplusplus
82}
83#endif
84
85#endif
diff --git a/kmicromail/libetpan/generic/mboxdriver_types.h b/kmicromail/libetpan/generic/mboxdriver_types.h
new file mode 100644
index 0000000..be31ea3
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxdriver_types.h
@@ -0,0 +1,107 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MBOXDRIVER_TYPES_H
37
38#define MBOXDRIVER_TYPES_H
39
40#include <libetpan/maildriver_types.h>
41#include <libetpan/mailmbox.h>
42#include <libetpan/mailstorage_types.h>
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48/* mbox driver */
49
50enum {
51 MBOXDRIVER_SET_READ_ONLY = 1,
52 MBOXDRIVER_SET_NO_UID,
53};
54
55struct mbox_session_state_data {
56 struct mailmbox_folder * mbox_folder;
57 int mbox_force_read_only;
58 int mbox_force_no_uid;
59};
60
61/* cached version */
62
63enum {
64 /* the mapping of the parameters should be the same as for mbox */
65 MBOXDRIVER_CACHED_SET_READ_ONLY = 1,
66 MBOXDRIVER_CACHED_SET_NO_UID,
67 /* cache specific */
68 MBOXDRIVER_CACHED_SET_CACHE_DIRECTORY,
69 MBOXDRIVER_CACHED_SET_FLAGS_DIRECTORY,
70};
71
72struct mbox_cached_session_state_data {
73 mailsession * mbox_ancestor;
74 char * mbox_quoted_mb;
75 char mbox_cache_directory[PATH_MAX];
76 char mbox_flags_directory[PATH_MAX];
77 struct mail_flags_store * mbox_flags_store;
78};
79
80/* mbox storage */
81
82/*
83 mbox_mailstorage is the state data specific to the mbox storage.
84
85 - pathname is the filename that contains the mailbox.
86
87 - cached if this value is != 0, a persistant cache will be
88 stored on local system.
89
90 - cache_directory is the location of the cache.
91
92 - flags_directory is the location of the flags.
93*/
94
95struct mbox_mailstorage {
96 char * mbox_pathname;
97
98 int mbox_cached;
99 char * mbox_cache_directory;
100 char * mbox_flags_directory;
101};
102
103#ifdef __cplusplus
104}
105#endif
106
107#endif
diff --git a/kmicromail/libetpan/generic/mboxstorage.c b/kmicromail/libetpan/generic/mboxstorage.c
new file mode 100644
index 0000000..0a7dc93
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxstorage.c
@@ -0,0 +1,192 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mboxstorage.h"
37
38#include "mail.h"
39#include "mailmessage.h"
40#include "mboxdriver.h"
41#include "mboxdriver_cached.h"
42#include "maildriver.h"
43
44#include <stdlib.h>
45#include <string.h>
46
47/* mbox storage */
48
49static int mbox_mailstorage_connect(struct mailstorage * storage);
50static int
51mbox_mailstorage_get_folder_session(struct mailstorage * storage,
52 char * pathname, mailsession ** result);
53static void mbox_mailstorage_uninitialize(struct mailstorage * storage);
54
55static mailstorage_driver mbox_mailstorage_driver = {
56 .sto_name = "mbox",
57 .sto_connect = mbox_mailstorage_connect,
58 .sto_get_folder_session = mbox_mailstorage_get_folder_session,
59 .sto_uninitialize = mbox_mailstorage_uninitialize,
60};
61
62int mbox_mailstorage_init(struct mailstorage * storage,
63 char * mbox_pathname, int mbox_cached,
64 char * mbox_cache_directory, char * mbox_flags_directory)
65{
66 struct mbox_mailstorage * mbox_storage;
67
68 mbox_storage = malloc(sizeof(struct mbox_mailstorage));
69 if (mbox_storage == NULL)
70 goto err;
71
72 mbox_storage->mbox_pathname = strdup(mbox_pathname);
73 if (mbox_storage->mbox_pathname == NULL)
74 goto free;
75
76 mbox_storage->mbox_cached = mbox_cached;
77
78 if (mbox_cached && (mbox_cache_directory != NULL) &&
79 (mbox_flags_directory != NULL)) {
80 mbox_storage->mbox_cache_directory = strdup(mbox_cache_directory);
81 if (mbox_storage->mbox_cache_directory == NULL)
82 goto free_pathname;
83
84 mbox_storage->mbox_flags_directory = strdup(mbox_flags_directory);
85 if (mbox_storage->mbox_flags_directory == NULL)
86 goto free_cache_directory;
87 }
88 else {
89 mbox_storage->mbox_cached = FALSE;
90 mbox_storage->mbox_cache_directory = NULL;
91 mbox_storage->mbox_flags_directory = NULL;
92 }
93
94 storage->sto_data = mbox_storage;
95 storage->sto_driver = &mbox_mailstorage_driver;
96
97 return MAIL_NO_ERROR;
98
99 free_cache_directory:
100 free(mbox_storage->mbox_cache_directory);
101 free_pathname:
102 free(mbox_storage->mbox_pathname);
103 free:
104 free(mbox_storage);
105 err:
106 return MAIL_ERROR_MEMORY;
107}
108
109static void mbox_mailstorage_uninitialize(struct mailstorage * storage)
110{
111 struct mbox_mailstorage * mbox_storage;
112
113 mbox_storage = storage->sto_data;
114 if (mbox_storage->mbox_flags_directory != NULL)
115 free(mbox_storage->mbox_flags_directory);
116 if (mbox_storage->mbox_cache_directory != NULL)
117 free(mbox_storage->mbox_cache_directory);
118 free(mbox_storage->mbox_pathname);
119 free(mbox_storage);
120
121 storage->sto_data = NULL;
122}
123
124static int mbox_mailstorage_connect(struct mailstorage * storage)
125{
126 struct mbox_mailstorage * mbox_storage;
127 mailsession_driver * driver;
128 int r;
129 int res;
130 mailsession * session;
131
132 mbox_storage = storage->sto_data;
133
134 if (mbox_storage->mbox_cached)
135 driver = mbox_cached_session_driver;
136 else
137 driver = mbox_session_driver;
138
139 session = mailsession_new(driver);
140 if (session == NULL) {
141 res = MAIL_ERROR_MEMORY;
142 goto err;
143 }
144
145 if (mbox_storage->mbox_cached) {
146 r = mailsession_parameters(session,
147 MBOXDRIVER_CACHED_SET_CACHE_DIRECTORY,
148 mbox_storage->mbox_cache_directory);
149 if (r != MAIL_NO_ERROR) {
150 res = r;
151 goto free;
152 }
153
154 r = mailsession_parameters(session,
155 MBOXDRIVER_CACHED_SET_FLAGS_DIRECTORY,
156 mbox_storage->mbox_flags_directory);
157 if (r != MAIL_NO_ERROR) {
158 res = r;
159 goto free;
160 }
161 }
162
163 r = mailsession_connect_path(session, mbox_storage->mbox_pathname);
164 switch (r) {
165 case MAIL_NO_ERROR_NON_AUTHENTICATED:
166 case MAIL_NO_ERROR_AUTHENTICATED:
167 case MAIL_NO_ERROR:
168 break;
169 default:
170 res = r;
171 goto free;
172 }
173
174 storage->sto_session = session;
175
176 return MAIL_NO_ERROR;
177
178 free:
179 mailsession_free(session);
180 err:
181 return res;
182}
183
184static int
185mbox_mailstorage_get_folder_session(struct mailstorage * storage,
186 char * pathname, mailsession ** result)
187{
188 * result = storage->sto_session;
189
190 return MAIL_NO_ERROR;
191}
192
diff --git a/kmicromail/libetpan/generic/mboxstorage.h b/kmicromail/libetpan/generic/mboxstorage.h
new file mode 100644
index 0000000..e5e83ce
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mboxstorage.h
@@ -0,0 +1,69 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MBOXSTORAGE_H
37
38#define MBOXSTORAGE_H
39
40#include <libetpan/mboxdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 mbox_mailstorage_init is the constructor for a mbox storage.
48
49 @param storage this is the storage to initialize.
50
51 @param pathname is the filename that contains the mailbox.
52
53 @param cached if this value is != 0, a persistant cache will be
54 stored on local system.
55
56 @param cache_directory is the location of the cache
57
58 @param flags_directory is the location of the flags
59*/
60
61int mbox_mailstorage_init(struct mailstorage * storage,
62 char * mb_pathname, int mb_cached,
63 char * mb_cache_directory, char * mb_flags_directory);
64
65#ifdef __cplusplus
66}
67#endif
68
69#endif
diff --git a/kmicromail/libetpan/generic/mhdriver.c b/kmicromail/libetpan/generic/mhdriver.c
new file mode 100644
index 0000000..af38d27
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver.c
@@ -0,0 +1,866 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mhdriver.h"
37
38#include <stdio.h>
39#include <sys/types.h>
40#include <dirent.h>
41#include <unistd.h>
42#include <sys/stat.h>
43#include <ctype.h>
44#include <fcntl.h>
45#include <sys/mman.h>
46#include <stdlib.h>
47#include <string.h>
48
49#include "mailmh.h"
50#include "maildriver_tools.h"
51#include "mhdriver_tools.h"
52#include "mhdriver_message.h"
53#include "mailmessage.h"
54
55static int mhdriver_initialize(mailsession * session);
56
57static void mhdriver_uninitialize(mailsession * session);
58
59static int mhdriver_connect_path(mailsession * session, char * path);
60static int mhdriver_logout(mailsession * session);
61
62static int mhdriver_build_folder_name(mailsession * session, char * mb,
63 char * name, char ** result);
64static int mhdriver_create_folder(mailsession * session, char * mb);
65
66static int mhdriver_delete_folder(mailsession * session, char * mb);
67
68static int mhdriver_rename_folder(mailsession * session, char * mb,
69 char * new_name);
70
71static int mhdriver_select_folder(mailsession * session, char * mb);
72
73static int mhdriver_status_folder(mailsession * session, char * mb,
74 uint32_t * result_messages, uint32_t * result_recent,
75 uint32_t * result_unseen);
76
77static int mhdriver_messages_number(mailsession * session, char * mb,
78 uint32_t * result);
79
80static int mhdriver_list_folders(mailsession * session, char * mb,
81 struct mail_list ** result);
82
83static int mhdriver_lsub_folders(mailsession * session, char * mb,
84 struct mail_list ** result);
85
86static int mhdriver_subscribe_folder(mailsession * session, char * mb);
87
88static int mhdriver_unsubscribe_folder(mailsession * session, char * mb);
89
90static int mhdriver_append_message(mailsession * session,
91 char * message, size_t size);
92static int mhdriver_copy_message(mailsession * session,
93 uint32_t num, char * mb);
94
95static int mhdriver_remove_message(mailsession * session, uint32_t num);
96
97static int mhdriver_move_message(mailsession * session,
98 uint32_t num, char * mb);
99
100static int mhdriver_get_messages_list(mailsession * session,
101 struct mailmessage_list ** result);
102
103static int mhdriver_get_message(mailsession * session,
104 uint32_t num, mailmessage ** result);
105
106static int mhdriver_get_message_by_uid(mailsession * session,
107 const char * uid,
108 mailmessage ** result);
109
110static mailsession_driver local_mh_session_driver = {
111 .sess_name = "mh",
112
113 .sess_initialize = mhdriver_initialize,
114 .sess_uninitialize = mhdriver_uninitialize,
115
116 .sess_parameters = NULL,
117
118 .sess_connect_stream = NULL,
119 .sess_connect_path = mhdriver_connect_path,
120 .sess_starttls = NULL,
121 .sess_login = NULL,
122 .sess_logout = mhdriver_logout,
123 .sess_noop = NULL,
124
125 .sess_build_folder_name = mhdriver_build_folder_name,
126 .sess_create_folder = mhdriver_create_folder,
127 .sess_delete_folder = mhdriver_delete_folder,
128 .sess_rename_folder = mhdriver_rename_folder,
129 .sess_check_folder = NULL,
130 .sess_examine_folder = NULL,
131 .sess_select_folder = mhdriver_select_folder,
132 .sess_expunge_folder = NULL,
133 .sess_status_folder = mhdriver_status_folder,
134 .sess_messages_number = mhdriver_messages_number,
135 .sess_recent_number = mhdriver_messages_number,
136 .sess_unseen_number = mhdriver_messages_number,
137 .sess_list_folders = mhdriver_list_folders,
138 .sess_lsub_folders = mhdriver_lsub_folders,
139 .sess_subscribe_folder = mhdriver_subscribe_folder,
140 .sess_unsubscribe_folder = mhdriver_unsubscribe_folder,
141
142 .sess_append_message = mhdriver_append_message,
143 .sess_copy_message = mhdriver_copy_message,
144 .sess_move_message = mhdriver_move_message,
145
146 .sess_get_messages_list = mhdriver_get_messages_list,
147 .sess_get_envelopes_list = maildriver_generic_get_envelopes_list,
148 .sess_remove_message = mhdriver_remove_message,
149#if 0
150 .sess_search_messages = maildriver_generic_search_messages,
151#endif
152
153 .sess_get_message = mhdriver_get_message,
154 .sess_get_message_by_uid = mhdriver_get_message_by_uid,
155};
156
157mailsession_driver * mh_session_driver = &local_mh_session_driver;
158
159static inline struct mh_session_state_data * get_data(mailsession * session)
160{
161 return session->sess_data;
162}
163
164static inline struct mailmh * get_mh_session(mailsession * session)
165{
166 return get_data(session)->mh_session;
167}
168
169static inline struct mailmh_folder * get_mh_cur_folder(mailsession * session)
170{
171 return get_data(session)->mh_cur_folder;
172}
173
174static int add_to_list(mailsession * session, char * mb)
175{
176 char * new_mb;
177 struct mh_session_state_data * data;
178 int r;
179
180 data = get_data(session);
181
182 new_mb = strdup(mb);
183 if (new_mb == NULL)
184 return -1;
185
186 r = clist_append(data->mh_subscribed_list, new_mb);
187 if (r < 0) {
188 free(mb);
189 return -1;
190 }
191
192 return 0;
193}
194
195static int remove_from_list(mailsession * session, char * mb)
196{
197 clistiter * cur;
198 struct mh_session_state_data * data;
199
200 data = get_data(session);
201
202 for(cur = clist_begin(data->mh_subscribed_list) ;
203 cur != NULL ; cur = clist_next(cur)) {
204 char * cur_name;
205
206 cur_name = clist_content(cur);
207 if (strcmp(cur_name, mb) == 0) {
208 clist_delete(data->mh_subscribed_list, cur);
209 free(cur_name);
210 return 0;
211 }
212 }
213
214 return -1;
215}
216
217static int mhdriver_initialize(mailsession * session)
218{
219 struct mh_session_state_data * data;
220
221 data = malloc(sizeof(* data));
222 if (data == NULL)
223 goto err;
224
225 data->mh_session = NULL;
226 data->mh_cur_folder = NULL;
227
228 data->mh_subscribed_list = clist_new();
229 if (data->mh_subscribed_list == NULL)
230 goto free;
231
232 session->sess_data = data;
233
234 return MAIL_NO_ERROR;
235
236 free:
237 free(data);
238 err:
239 return MAIL_ERROR_MEMORY;
240}
241
242static void mhdriver_uninitialize(mailsession * session)
243{
244 struct mh_session_state_data * data;
245
246 data = get_data(session);
247
248 if (data->mh_session != NULL)
249 mailmh_free(data->mh_session);
250
251 clist_foreach(data->mh_subscribed_list, (clist_func) free, NULL);
252 clist_free(data->mh_subscribed_list);
253
254 free(data);
255
256 session->sess_data = NULL;
257}
258
259
260static int mhdriver_connect_path(mailsession * session, char * path)
261{
262 struct mailmh * mh;
263
264 if (get_mh_session(session) != NULL)
265 return MAIL_ERROR_BAD_STATE;
266
267 mh = mailmh_new(path);
268 if (mh == NULL)
269 return MAIL_ERROR_MEMORY;
270
271 get_data(session)->mh_session = mh;
272
273 return MAIL_NO_ERROR;
274}
275
276static int mhdriver_logout(mailsession * session)
277{
278 struct mailmh * mh;
279
280 mh = get_mh_session(session);
281
282 if (mh == NULL)
283 return MAIL_ERROR_BAD_STATE;
284
285 mailmh_free(mh);
286 get_data(session)->mh_session = NULL;
287
288 return MAIL_NO_ERROR;
289}
290
291/* folders operations */
292
293static int mhdriver_build_folder_name(mailsession * session, char * mb,
294 char * name, char ** result)
295{
296 char * folder_name;
297
298 folder_name = malloc(strlen(mb) + 2 + strlen(name));
299 if (folder_name == NULL)
300 return MAIL_ERROR_MEMORY;
301
302 strcpy(folder_name, mb);
303 strcat(folder_name, "/");
304 strcat(folder_name, name);
305
306 * result = folder_name;
307
308 return MAIL_NO_ERROR;
309}
310
311static int get_parent(mailsession * session, char * mb,
312 struct mailmh_folder ** result_folder,
313 char ** result_name)
314{
315 char * name;
316 size_t length;
317 int i;
318 char * parent_name;
319 struct mailmh_folder * parent;
320 struct mailmh * mh;
321
322 mh = get_mh_session(session);
323 if (mh == NULL)
324 return MAIL_ERROR_BAD_STATE;
325
326 length = strlen(mb);
327 for(i = length - 1 ; i >= 0 ; i--)
328 if (mb[i] == '/')
329 break;
330 name = mb + i + 1;
331
332 parent_name = malloc(i + 1);
333 /* strndup(mb, i) */
334 if (parent_name == NULL)
335 return MAIL_ERROR_MEMORY;
336
337 strncpy(parent_name, mb, i);
338 parent_name[i] = '\0';
339
340 parent = mailmh_folder_find(mh->mh_main, parent_name);
341 free(parent_name);
342 if (parent == NULL)
343 return MAIL_ERROR_FOLDER_NOT_FOUND;
344
345 * result_folder = parent;
346 * result_name = name;
347
348 return MAIL_NO_ERROR;
349}
350
351static int mhdriver_create_folder(mailsession * session, char * mb)
352{
353 int r;
354 struct mailmh_folder * parent;
355 char * name;
356
357 r = get_parent(session, mb, &parent, &name);
358 if (r != MAIL_NO_ERROR)
359 return r;
360
361 r = mailmh_folder_add_subfolder(parent, name);
362
363 return mhdriver_mh_error_to_mail_error(r);
364}
365
366static int mhdriver_delete_folder(mailsession * session, char * mb)
367{
368 int r;
369 struct mailmh_folder * folder;
370 struct mailmh * mh;
371
372 mh = get_mh_session(session);
373 if (mh == NULL)
374 return MAIL_ERROR_BAD_STATE;
375
376 folder = mailmh_folder_find(mh->mh_main, mb);
377 if (folder == NULL)
378 return MAIL_ERROR_FOLDER_NOT_FOUND;
379
380 if (get_mh_cur_folder(session) == folder)
381 get_data(session)->mh_cur_folder = NULL;
382
383 r = mailmh_folder_remove_subfolder(folder);
384
385 return mhdriver_mh_error_to_mail_error(r);
386}
387
388static int mhdriver_rename_folder(mailsession * session, char * mb,
389 char * new_name)
390{
391 struct mailmh_folder * src_folder;
392 struct mailmh_folder * dst_folder;
393 char * name;
394 struct mailmh * mh;
395 int r;
396
397 r = get_parent(session, new_name, &dst_folder, &name);
398 if (r != MAIL_NO_ERROR)
399 return r;
400
401 mh = get_mh_session(session);
402 if (mh == NULL)
403 return MAIL_ERROR_BAD_STATE;
404
405 src_folder = mailmh_folder_find(mh->mh_main, mb);
406 if (src_folder == NULL)
407 return MAIL_ERROR_FOLDER_NOT_FOUND;
408
409 if (get_mh_cur_folder(session) == src_folder)
410 get_data(session)->mh_cur_folder = NULL;
411
412 r = mailmh_folder_rename_subfolder(src_folder, dst_folder, name);
413
414 return mhdriver_mh_error_to_mail_error(r);
415}
416
417static int mhdriver_select_folder(mailsession * session, char * mb)
418{
419 struct mailmh_folder * folder;
420 struct mailmh * mh;
421 int r;
422
423 mh = get_mh_session(session);
424 if (mh == NULL)
425 return MAIL_ERROR_BAD_STATE;
426
427 r = mailmh_folder_update(mh->mh_main);
428
429 folder = mailmh_folder_find(mh->mh_main, mb);
430 if (folder == NULL)
431 return MAIL_ERROR_FOLDER_NOT_FOUND;
432
433 get_data(session)->mh_cur_folder = folder;
434 r = mailmh_folder_update(folder);
435
436 return mhdriver_mh_error_to_mail_error(r);
437}
438
439static int mhdriver_status_folder(mailsession * session, char * mb,
440 uint32_t * result_messages, uint32_t * result_recent,
441 uint32_t * result_unseen)
442{
443 uint32_t count;
444 int r;
445
446 r = mhdriver_messages_number(session, mb, &count);
447 if (r != MAIL_NO_ERROR)
448 return r;
449
450 * result_messages = count;
451 * result_recent = count;
452 * result_unseen = count;
453
454 return MAIL_NO_ERROR;
455}
456
457static int mhdriver_messages_number(mailsession * session, char * mb,
458 uint32_t * result)
459{
460 struct mailmh_folder * folder;
461 uint32_t count;
462 struct mailmh * mh;
463 unsigned int i;
464
465 mh = get_mh_session(session);
466 if (mh == NULL)
467 return MAIL_ERROR_BAD_STATE;
468
469 if (mb != NULL) {
470 folder = mailmh_folder_find(mh->mh_main, mb);
471 if (folder == NULL)
472 return MAIL_ERROR_FOLDER_NOT_FOUND;
473 }
474 else {
475 folder = get_mh_cur_folder(session);
476 if (folder == NULL)
477 return MAIL_ERROR_BAD_STATE;
478 }
479
480 mailmh_folder_update(folder);
481 count = 0;
482 for (i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) {
483 struct mailmh_msg_info * msg_info;
484
485 msg_info = carray_get(folder->fl_msgs_tab, i);
486 if (msg_info != NULL)
487 count ++;
488 }
489
490 * result = count;
491
492 return MAIL_NO_ERROR;
493}
494
495
496static int get_list_folders(struct mailmh_folder * folder, clist ** result)
497{
498 unsigned int i;
499 clist * list;
500 char * new_filename;
501 int res;
502 int r;
503
504 list = * result;
505
506 new_filename = strdup(folder->fl_filename);
507 if (new_filename == NULL) {
508 res = MAIL_ERROR_MEMORY;
509 goto free;
510 }
511
512 r = mailmh_folder_update(folder);
513
514 switch (r) {
515 case MAILMH_NO_ERROR:
516 break;
517
518 default:
519 res = mhdriver_mh_error_to_mail_error(r);
520 goto free;
521 }
522
523 r = clist_append(list, new_filename);
524 if (r < 0) {
525 free(new_filename);
526 res = MAIL_ERROR_MEMORY;
527 goto free;
528 }
529
530 if (folder->fl_subfolders_tab != NULL) {
531 for(i = 0 ; i < carray_count(folder->fl_subfolders_tab) ; i++) {
532 struct mailmh_folder * subfolder;
533
534 subfolder = carray_get(folder->fl_subfolders_tab, i);
535
536 r = get_list_folders(subfolder, &list);
537 if (r != MAIL_NO_ERROR) {
538 res = MAIL_ERROR_MEMORY;
539 goto free;
540 }
541 }
542 }
543
544 * result = list;
545
546 return MAIL_NO_ERROR;
547
548 free:
549 clist_foreach(list, (clist_func) free, NULL);
550 clist_free(list);
551 return res;
552}
553
554
555static int mhdriver_list_folders(mailsession * session, char * mb,
556 struct mail_list ** result)
557{
558 clist * list;
559 int r;
560 struct mailmh * mh;
561 struct mail_list * ml;
562
563 mh = get_mh_session(session);
564
565 if (mh == NULL)
566 return MAIL_ERROR_BAD_STATE;
567
568 list = clist_new();
569 if (list == NULL)
570 return MAIL_ERROR_MEMORY;
571
572 r = get_list_folders(mh->mh_main, &list);
573 if (r != MAIL_NO_ERROR)
574 return r;
575
576 ml = mail_list_new(list);
577 if (ml == NULL)
578 goto free;
579
580 * result = ml;
581
582 return MAIL_NO_ERROR;
583
584 free:
585 clist_foreach(list, (clist_func) free, NULL);
586 clist_free(list);
587 return MAIL_ERROR_MEMORY;
588}
589
590static int mhdriver_lsub_folders(mailsession * session, char * mb,
591 struct mail_list ** result)
592{
593 clist * subscribed;
594 clist * lsub_result;
595 clistiter * cur;
596 struct mail_list * lsub;
597 size_t length;
598 int r;
599
600 length = strlen(mb);
601
602 subscribed = get_data(session)->mh_subscribed_list;
603
604 lsub_result = clist_new();
605 if (lsub_result == NULL)
606 return MAIL_ERROR_MEMORY;
607
608 for(cur = clist_begin(subscribed) ; cur != NULL ;
609 cur = clist_next(cur)) {
610 char * cur_mb;
611 char * new_mb;
612
613 cur_mb = clist_content(cur);
614
615 if (strncmp(mb, cur_mb, length) == 0) {
616 new_mb = strdup(cur_mb);
617 if (new_mb == NULL)
618 goto free_list;
619
620 r = clist_append(lsub_result, new_mb);
621 if (r < 0) {
622 free(new_mb);
623 goto free_list;
624 }
625 }
626 }
627
628 lsub = mail_list_new(lsub_result);
629 if (lsub == NULL)
630 goto free_list;
631
632 * result = lsub;
633
634 return MAIL_NO_ERROR;
635
636 free_list:
637 clist_foreach(lsub_result, (clist_func) free, NULL);
638 clist_free(lsub_result);
639 return MAIL_ERROR_MEMORY;
640}
641
642static int mhdriver_subscribe_folder(mailsession * session, char * mb)
643{
644 int r;
645
646 r = add_to_list(session, mb);
647 if (r < 0)
648 return MAIL_ERROR_SUBSCRIBE;
649
650 return MAIL_NO_ERROR;
651}
652
653static int mhdriver_unsubscribe_folder(mailsession * session, char * mb)
654{
655 int r;
656
657 r = remove_from_list(session, mb);
658 if (r < 0)
659 return MAIL_ERROR_UNSUBSCRIBE;
660
661 return MAIL_NO_ERROR;
662}
663
664/* messages operations */
665
666static int mhdriver_append_message(mailsession * session,
667 char * message, size_t size)
668{
669 int r;
670 struct mailmh_folder * folder;
671
672 folder = get_mh_cur_folder(session);
673 if (folder == NULL)
674 return MAIL_ERROR_BAD_STATE;
675
676 r = mailmh_folder_add_message(folder, message, size);
677
678 switch (r) {
679 case MAILMH_ERROR_FILE:
680 return MAIL_ERROR_DISKSPACE;
681
682 default:
683 return mhdriver_mh_error_to_mail_error(r);
684 }
685}
686
687static int mhdriver_copy_message(mailsession * session,
688 uint32_t num, char * mb)
689{
690 int fd;
691 int r;
692 struct mailmh_folder * folder;
693 struct mailmh * mh;
694 int res;
695
696 mh = get_mh_session(session);
697 if (mh == NULL) {
698 res = MAIL_ERROR_BAD_STATE;
699 goto err;
700 }
701
702 folder = get_mh_cur_folder(session);
703 if (folder == NULL) {
704 res = MAIL_ERROR_BAD_STATE;
705 goto err;
706 }
707
708 r = mailmh_folder_get_message_fd(folder, num, O_RDONLY, &fd);
709 if (r != MAIL_NO_ERROR) {
710 res = r;
711 goto err;
712 }
713
714 folder = mailmh_folder_find(mh->mh_main, mb);
715 if (folder == NULL) {
716 res = MAIL_ERROR_FOLDER_NOT_FOUND;
717 goto close;
718 }
719
720 r = mailmh_folder_add_message_file(folder, fd);
721 if (r != MAIL_NO_ERROR) {
722 res = MAIL_ERROR_COPY;
723 goto close;
724 }
725
726 close(fd);
727
728 return MAIL_NO_ERROR;
729
730 close:
731 close(fd);
732 err:
733 return res;
734}
735
736static int mhdriver_remove_message(mailsession * session, uint32_t num)
737{
738 int r;
739 struct mailmh_folder * folder;
740
741 folder = get_mh_cur_folder(session);
742 if (folder == NULL)
743 return MAIL_ERROR_DELETE;
744
745 r = mailmh_folder_remove_message(folder, num);
746
747 return mhdriver_mh_error_to_mail_error(r);
748}
749
750static int mhdriver_move_message(mailsession * session,
751 uint32_t num, char * mb)
752{
753 int r;
754 struct mailmh_folder * src_folder;
755 struct mailmh_folder * dest_folder;
756 struct mailmh * mh;
757
758 mh = get_mh_session(session);
759 if (mh == NULL)
760 return MAIL_ERROR_BAD_STATE;
761
762 src_folder = get_mh_cur_folder(session);
763 if (src_folder == NULL)
764 return MAIL_ERROR_BAD_STATE;
765
766 dest_folder = mailmh_folder_find(mh->mh_main, mb);
767 if (dest_folder == NULL)
768 return MAIL_ERROR_FOLDER_NOT_FOUND;
769
770 r = mailmh_folder_move_message(dest_folder, src_folder, num);
771
772 return mhdriver_mh_error_to_mail_error(r);
773}
774
775
776static int mhdriver_get_messages_list(mailsession * session,
777 struct mailmessage_list ** result)
778{
779 struct mailmh_folder * folder;
780 int res;
781
782 folder = get_mh_cur_folder(session);
783 if (folder == NULL) {
784 res = MAIL_ERROR_BAD_STATE;
785 goto err;
786 }
787
788 mailmh_folder_update(folder);
789 return mh_get_messages_list(folder, session, mh_message_driver, result);
790
791 err:
792 return res;
793}
794
795static int mhdriver_get_message(mailsession * session,
796 uint32_t num, mailmessage ** result)
797{
798 mailmessage * msg_info;
799 int r;
800
801 msg_info = mailmessage_new();
802 if (msg_info == NULL)
803 return MAIL_ERROR_MEMORY;
804
805 r = mailmessage_init(msg_info, session, mh_message_driver, num, 0);
806 if (r != MAIL_NO_ERROR) {
807 mailmessage_free(msg_info);
808 return r;
809 }
810
811 * result = msg_info;
812
813 return MAIL_NO_ERROR;
814}
815
816static int mhdriver_get_message_by_uid(mailsession * session,
817 const char * uid,
818 mailmessage ** result)
819{
820 uint32_t index;
821 char *p;
822 struct mailmh_msg_info * mh_msg_info;
823 struct mh_session_state_data * mh_data;
824 chashdatum key;
825 chashdatum data;
826 int r;
827 time_t mtime;
828 char * mtime_p;
829
830 if (uid == NULL)
831 return MAIL_ERROR_INVAL;
832
833 index = strtoul(uid, &p, 10);
834 if (p == uid || * p != '-')
835 return MAIL_ERROR_INVAL;
836
837 mh_data = session->sess_data;
838#if 0
839 mh_msg_info = cinthash_find(mh_data->mh_cur_folder->fl_msgs_hash, index);
840#endif
841 key.data = &index;
842 key.len = sizeof(index);
843 r = chash_get(mh_data->mh_cur_folder->fl_msgs_hash, &key, &data);
844 if (r < 0)
845 return MAIL_ERROR_MSG_NOT_FOUND;
846
847 mh_msg_info = data.data;
848
849 mtime_p = p + 1;
850
851 mtime = strtoul(mtime_p, &p, 10);
852 if ((* p == '-') && (mtime == mh_msg_info->msg_mtime)) {
853 size_t size;
854 char *size_p;
855
856 size_p = p + 1;
857 size = strtoul(size_p, &p, 10);
858 if ((* p == '\0') && (size == mh_msg_info->msg_size))
859 return mhdriver_get_message(session, index, result);
860 }
861 else if (* p != '-') {
862 return MAIL_ERROR_INVAL;
863 }
864
865 return MAIL_ERROR_MSG_NOT_FOUND;
866}
diff --git a/kmicromail/libetpan/generic/mhdriver.h b/kmicromail/libetpan/generic/mhdriver.h
new file mode 100644
index 0000000..a82b9c1
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MHDRIVER_H
37
38#define MHDRIVER_H
39
40#include <libetpan/maildriver.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * mh_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/mhdriver_cached.c b/kmicromail/libetpan/generic/mhdriver_cached.c
new file mode 100644
index 0000000..5c35089
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_cached.c
@@ -0,0 +1,1232 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mhdriver_cached.h"
37
38#include <stdio.h>
39#include <sys/types.h>
40#include <dirent.h>
41#include <unistd.h>
42#include <sys/stat.h>
43#include <ctype.h>
44#include <fcntl.h>
45#include <sys/mman.h>
46#include <stdlib.h>
47#include <string.h>
48
49#include "mail.h"
50#include "mail_cache_db.h"
51
52#include "generic_cache.h"
53#include "imfcache.h"
54#include "mhdriver.h"
55
56#include "mhdriver_cached_message.h"
57#include "mailmh.h"
58#include "maildriver_tools.h"
59#include "mhdriver_tools.h"
60#include "mailmessage.h"
61
62static int mhdriver_cached_initialize(mailsession * session);
63
64static void mhdriver_cached_uninitialize(mailsession * session);
65
66static int mhdriver_cached_parameters(mailsession * session,
67 int id, void * value);
68
69static int mhdriver_cached_connect_path(mailsession * session, char * path);
70static int mhdriver_cached_logout(mailsession * session);
71
72static int mhdriver_cached_build_folder_name(mailsession * session, char * mb,
73 char * name, char ** result);
74static int mhdriver_cached_create_folder(mailsession * session, char * mb);
75
76static int mhdriver_cached_delete_folder(mailsession * session, char * mb);
77
78static int mhdriver_cached_rename_folder(mailsession * session, char * mb,
79 char * new_name);
80
81static int mhdriver_cached_check_folder(mailsession * session);
82
83static int mhdriver_cached_select_folder(mailsession * session, char * mb);
84
85static int mhdriver_cached_expunge_folder(mailsession * session);
86
87static int mhdriver_cached_status_folder(mailsession * session, char * mb,
88 uint32_t * result_messages, uint32_t * result_recent,
89 uint32_t * result_unseen);
90
91static int mhdriver_cached_messages_number(mailsession * session, char * mb,
92 uint32_t * result);
93static int mhdriver_cached_recent_number(mailsession * session, char * mb,
94 uint32_t * result);
95static int mhdriver_cached_unseen_number(mailsession * session, char * mb,
96 uint32_t * result);
97
98static int mhdriver_cached_list_folders(mailsession * session, char * mb,
99 struct mail_list ** result);
100
101static int mhdriver_cached_lsub_folders(mailsession * session, char * mb,
102 struct mail_list ** result);
103
104static int mhdriver_cached_subscribe_folder(mailsession * session, char * mb);
105
106static int mhdriver_cached_unsubscribe_folder(mailsession * session,
107 char * mb);
108
109static int mhdriver_cached_append_message(mailsession * session,
110 char * message, size_t size);
111static int mhdriver_cached_copy_message(mailsession * session,
112 uint32_t num, char * mb);
113
114static int mhdriver_cached_remove_message(mailsession * session,
115 uint32_t num);
116
117static int mhdriver_cached_move_message(mailsession * session,
118 uint32_t num, char * mb);
119
120static int
121mhdriver_cached_get_messages_list(mailsession * session,
122 struct mailmessage_list ** result);
123
124static int
125mhdriver_cached_get_envelopes_list(mailsession * session,
126 struct mailmessage_list * env_list);
127
128static int mhdriver_cached_get_message(mailsession * session,
129 uint32_t num, mailmessage ** result);
130
131static int mhdriver_cached_get_message_by_uid(mailsession * session,
132 const char * uid,
133 mailmessage ** result);
134
135static mailsession_driver local_mh_cached_session_driver = {
136 .sess_name = "mh-cached",
137
138 .sess_initialize = mhdriver_cached_initialize,
139 .sess_uninitialize = mhdriver_cached_uninitialize,
140
141 .sess_parameters = mhdriver_cached_parameters,
142
143 .sess_connect_stream = NULL,
144 .sess_connect_path = mhdriver_cached_connect_path,
145 .sess_starttls = NULL,
146 .sess_login = NULL,
147 .sess_logout = mhdriver_cached_logout,
148 .sess_noop = NULL,
149
150 .sess_build_folder_name = mhdriver_cached_build_folder_name,
151 .sess_create_folder = mhdriver_cached_create_folder,
152 .sess_delete_folder = mhdriver_cached_delete_folder,
153 .sess_rename_folder = mhdriver_cached_rename_folder,
154 .sess_check_folder = mhdriver_cached_check_folder,
155 .sess_examine_folder = NULL,
156 .sess_select_folder = mhdriver_cached_select_folder,
157 .sess_expunge_folder = mhdriver_cached_expunge_folder,
158 .sess_status_folder = mhdriver_cached_status_folder,
159 .sess_messages_number = mhdriver_cached_messages_number,
160 .sess_recent_number = mhdriver_cached_recent_number,
161 .sess_unseen_number = mhdriver_cached_unseen_number,
162 .sess_list_folders = mhdriver_cached_list_folders,
163 .sess_lsub_folders = mhdriver_cached_lsub_folders,
164 .sess_subscribe_folder = mhdriver_cached_subscribe_folder,
165 .sess_unsubscribe_folder = mhdriver_cached_unsubscribe_folder,
166
167 .sess_append_message = mhdriver_cached_append_message,
168 .sess_copy_message = mhdriver_cached_copy_message,
169 .sess_move_message = mhdriver_cached_move_message,
170
171 .sess_get_messages_list = mhdriver_cached_get_messages_list,
172 .sess_get_envelopes_list = mhdriver_cached_get_envelopes_list,
173 .sess_remove_message = mhdriver_cached_remove_message,
174#if 0
175 .sess_search_messages = maildriver_generic_search_messages,
176#endif
177
178 .sess_get_message = mhdriver_cached_get_message,
179 .sess_get_message_by_uid = mhdriver_cached_get_message_by_uid,
180};
181
182mailsession_driver * mh_cached_session_driver =
183&local_mh_cached_session_driver;
184
185#define ENV_NAME "env.db"
186#define FLAGS_NAME "flags.db"
187
188
189static inline struct mh_cached_session_state_data *
190get_cached_data(mailsession * session)
191{
192 return session->sess_data;
193}
194
195static inline mailsession * get_ancestor(mailsession * session)
196{
197 return get_cached_data(session)->mh_ancestor;
198}
199
200static inline struct mh_session_state_data *
201get_ancestor_data(mailsession * session)
202{
203 return get_ancestor(session)->sess_data;
204}
205
206static inline struct mailmh *
207get_mh_session(mailsession * session)
208{
209 return get_ancestor_data(session)->mh_session;
210}
211
212static inline struct mailmh_folder *
213get_mh_cur_folder(mailsession * session)
214{
215 return get_ancestor_data(session)->mh_cur_folder;
216}
217
218
219#define FILENAME_MAX_UID "max-uid"
220
221/* write max uid current value */
222
223static int write_max_uid_value(mailsession * session)
224{
225 int r;
226 char filename[PATH_MAX];
227 FILE * f;
228 int res;
229 struct mh_cached_session_state_data * cached_data;
230 struct mh_session_state_data * ancestor_data;
231 int fd;
232
233 MMAPString * mmapstr;
234 size_t cur_token;
235
236 cached_data = get_cached_data(session);
237 ancestor_data = get_ancestor_data(session);
238
239 if (cached_data->mh_quoted_mb == NULL)
240 return MAIL_ERROR_BAD_STATE;
241
242 snprintf(filename, PATH_MAX, "%s/%s/%s",
243 cached_data->mh_cache_directory,
244 cached_data->mh_quoted_mb, FILENAME_MAX_UID);
245
246 fd = creat(filename, S_IRUSR | S_IWUSR);
247 if (fd < 0) {
248 res = MAIL_ERROR_FILE;
249 goto err;
250 }
251
252 f = fdopen(fd, "w");
253 if (f == NULL) {
254 close(fd);
255 res = MAIL_ERROR_FILE;
256 goto err;
257 }
258
259 mmapstr = mmap_string_new("");
260 if (mmapstr == NULL) {
261 res = MAIL_ERROR_MEMORY;
262 goto close;
263 }
264
265 r = mail_serialize_clear(mmapstr, &cur_token);
266 if (r != MAIL_NO_ERROR) {
267 res = r;
268 goto free_mmapstr;
269 }
270
271 r = mailimf_cache_int_write(mmapstr, &cur_token,
272 ancestor_data->mh_cur_folder->fl_max_index);
273 if (r != MAIL_NO_ERROR) {
274 res = r;
275 goto free_mmapstr;
276 }
277
278 fwrite(mmapstr->str, 1, mmapstr->len, f);
279
280 mmap_string_free(mmapstr);
281 fclose(f);
282
283 return MAIL_NO_ERROR;
284
285 free_mmapstr:
286 mmap_string_free(mmapstr);
287 close:
288 fclose(f);
289 err:
290 return res;
291}
292
293static int read_max_uid_value(mailsession * session)
294{
295 int r;
296 char filename[PATH_MAX];
297 FILE * f;
298 uint32_t written_uid;
299 int res;
300 struct mh_cached_session_state_data * cached_data;
301 struct mh_session_state_data * ancestor_data;
302
303 MMAPString * mmapstr;
304 size_t cur_token;
305 char buf[sizeof(uint32_t)];
306 size_t read_size;
307
308 cached_data = get_cached_data(session);
309 ancestor_data = get_ancestor_data(session);
310
311 snprintf(filename, PATH_MAX, "%s/%s/%s",
312 cached_data->mh_cache_directory,
313 cached_data->mh_quoted_mb, FILENAME_MAX_UID);
314
315 f = fopen(filename, "r");
316 if (f == NULL) {
317 res = MAIL_ERROR_FILE;
318 goto err;
319 }
320
321 read_size = fread(buf, 1, sizeof(uint32_t), f);
322
323 mmapstr = mmap_string_new_len(buf, read_size);
324 if (mmapstr == NULL) {
325 res = MAIL_ERROR_MEMORY;
326 goto close;
327 }
328
329 cur_token = 0;
330
331 r = mailimf_cache_int_read(mmapstr, &cur_token, &written_uid);
332 if (r != MAIL_NO_ERROR) {
333 fclose(f);
334 res = r;
335 goto free_mmapstr;
336 }
337
338 mmap_string_free(mmapstr);
339 fclose(f);
340
341 if (written_uid > ancestor_data->mh_cur_folder->fl_max_index)
342 ancestor_data->mh_cur_folder->fl_max_index = written_uid;
343
344 return MAIL_NO_ERROR;
345
346 free_mmapstr:
347 mmap_string_free(mmapstr);
348 close:
349 fclose(f);
350 err:
351 return res;
352}
353
354
355static int mhdriver_cached_initialize(mailsession * session)
356{
357 struct mh_cached_session_state_data * data;
358
359 data = malloc(sizeof(* data));
360 if (data == NULL)
361 goto err;
362
363 data->mh_flags_store = mail_flags_store_new();
364 if (data->mh_flags_store == NULL)
365 goto free;
366
367 data->mh_ancestor = mailsession_new(mh_session_driver);
368 if (data->mh_ancestor == NULL)
369 goto free_store;
370
371 data->mh_quoted_mb = NULL;
372
373 session->sess_data = data;
374
375 return MAIL_NO_ERROR;
376
377 free_store:
378 mail_flags_store_free(data->mh_flags_store);
379 free:
380 free(data);
381 err:
382 return MAIL_ERROR_MEMORY;
383}
384
385static void free_state(struct mh_cached_session_state_data * mh_data)
386{
387 if (mh_data->mh_quoted_mb) {
388 free(mh_data->mh_quoted_mb);
389 mh_data->mh_quoted_mb = NULL;
390 }
391}
392
393static int mh_flags_store_process(char * flags_directory, char * quoted_mb,
394 struct mail_flags_store * flags_store)
395{
396 char filename_flags[PATH_MAX];
397 struct mail_cache_db * cache_db_flags;
398 MMAPString * mmapstr;
399 unsigned int i;
400 int r;
401 int res;
402
403 if (carray_count(flags_store->fls_tab) == 0)
404 return MAIL_NO_ERROR;
405
406 if (quoted_mb == NULL)
407 return MAIL_NO_ERROR;
408
409 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
410 flags_directory, quoted_mb, FLAGS_NAME);
411
412 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
413 if (r < 0) {
414 res = MAIL_ERROR_FILE;
415 goto err;
416 }
417
418 mmapstr = mmap_string_new("");
419 if (mmapstr == NULL) {
420 res = MAIL_ERROR_MEMORY;
421 goto close_db_flags;
422 }
423
424 for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
425 mailmessage * msg;
426
427 msg = carray_get(flags_store->fls_tab, i);
428
429 r = mhdriver_write_cached_flags(cache_db_flags, mmapstr,
430 msg->msg_uid, msg->msg_flags);
431 }
432
433 mmap_string_free(mmapstr);
434 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
435
436 mail_flags_store_clear(flags_store);
437
438 return MAIL_NO_ERROR;
439
440 close_db_flags:
441 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
442 err:
443 return res;
444}
445
446static void mhdriver_cached_uninitialize(mailsession * session)
447{
448 struct mh_cached_session_state_data * data;
449
450 data = get_cached_data(session);
451
452 mh_flags_store_process(data->mh_flags_directory, data->mh_quoted_mb,
453 data->mh_flags_store);
454
455 mail_flags_store_free(data->mh_flags_store);
456
457 free_state(data);
458 mailsession_free(data->mh_ancestor);
459 free(data);
460
461 session->sess_data = NULL;
462}
463
464static int mhdriver_cached_parameters(mailsession * session,
465 int id, void * value)
466{
467 struct mh_cached_session_state_data * cached_data;
468 int r;
469
470 cached_data = get_cached_data(session);
471
472 switch (id) {
473 case MHDRIVER_CACHED_SET_CACHE_DIRECTORY:
474 strncpy(cached_data->mh_cache_directory, value, PATH_MAX);
475 cached_data->mh_cache_directory[PATH_MAX - 1] = '\0';
476
477 r = generic_cache_create_dir(cached_data->mh_cache_directory);
478 if (r != MAIL_NO_ERROR)
479 return r;
480
481 return MAIL_NO_ERROR;
482
483 case MHDRIVER_CACHED_SET_FLAGS_DIRECTORY:
484 strncpy(cached_data->mh_flags_directory, value, PATH_MAX);
485 cached_data->mh_flags_directory[PATH_MAX - 1] = '\0';
486
487 r = generic_cache_create_dir(cached_data->mh_flags_directory);
488 if (r != MAIL_NO_ERROR)
489 return r;
490
491 return MAIL_NO_ERROR;
492 }
493
494 return MAIL_ERROR_INVAL;
495}
496
497static int mhdriver_cached_connect_path(mailsession * session, char * path)
498{
499 return mailsession_connect_path(get_ancestor(session), path);
500}
501
502static int mhdriver_cached_logout(mailsession * session)
503{
504 int r;
505 struct mh_cached_session_state_data * cached_data;
506
507 r = write_max_uid_value(session);
508
509 cached_data = get_cached_data(session);
510
511 mh_flags_store_process(cached_data->mh_flags_directory,
512 cached_data->mh_quoted_mb,
513 cached_data->mh_flags_store);
514
515 return mailsession_logout(get_ancestor(session));
516}
517
518static int mhdriver_cached_check_folder(mailsession * session)
519{
520 struct mh_cached_session_state_data * cached_data;
521
522 cached_data = get_cached_data(session);
523
524 mh_flags_store_process(cached_data->mh_flags_directory,
525 cached_data->mh_quoted_mb,
526 cached_data->mh_flags_store);
527
528 return MAIL_NO_ERROR;
529}
530
531/* folders operations */
532
533static int mhdriver_cached_build_folder_name(mailsession * session, char * mb,
534 char * name, char ** result)
535{
536 return mailsession_build_folder_name(get_ancestor(session),
537 mb, name, result);
538}
539
540static int mhdriver_cached_create_folder(mailsession * session, char * mb)
541{
542 return mailsession_create_folder(get_ancestor(session), mb);
543}
544
545static int mhdriver_cached_delete_folder(mailsession * session, char * mb)
546{
547 return mailsession_delete_folder(get_ancestor(session), mb);
548}
549
550static int mhdriver_cached_rename_folder(mailsession * session, char * mb,
551 char * new_name)
552{
553 return mailsession_rename_folder(get_ancestor(session), mb, new_name);
554}
555
556static int get_cache_directory(mailsession * session,
557 char * path, char ** result)
558{
559 char * quoted_mb;
560 char dirname[PATH_MAX];
561 int res;
562 int r;
563 struct mh_cached_session_state_data * cached_data;
564
565 cached_data = get_cached_data(session);
566
567 quoted_mb = maildriver_quote_mailbox(path);
568 if (quoted_mb == NULL) {
569 res = MAIL_ERROR_MEMORY;
570 goto err;
571 }
572
573 snprintf(dirname, PATH_MAX, "%s/%s",
574 cached_data->mh_cache_directory, quoted_mb);
575
576 r = generic_cache_create_dir(dirname);
577 if (r != MAIL_NO_ERROR) {
578 res = r;
579 goto free;
580 }
581
582 snprintf(dirname, PATH_MAX, "%s/%s",
583 cached_data->mh_flags_directory, quoted_mb);
584
585 r = generic_cache_create_dir(dirname);
586 if (r != MAIL_NO_ERROR) {
587 res = r;
588 goto free;
589 }
590
591 * result = quoted_mb;
592
593 return MAIL_NO_ERROR;
594
595 free:
596 free(quoted_mb);
597 err:
598 return res;
599}
600
601static int mhdriver_cached_select_folder(mailsession * session, char * mb)
602{
603 int r;
604 int res;
605 char * quoted_mb;
606 struct mh_cached_session_state_data * cached_data;
607
608 cached_data = get_cached_data(session);
609
610 mh_flags_store_process(cached_data->mh_flags_directory,
611 cached_data->mh_quoted_mb,
612 cached_data->mh_flags_store);
613
614 r = get_cache_directory(session, mb, &quoted_mb);
615 if (r != MAIL_NO_ERROR) {
616 res = r;
617 goto err;
618 }
619
620 r = mailsession_select_folder(get_ancestor(session), mb);
621 if (r != MAIL_NO_ERROR) {
622 res = r;
623 goto free;
624 }
625
626 r = write_max_uid_value(session);
627
628 free_state(cached_data);
629 cached_data->mh_quoted_mb = quoted_mb;
630
631 r = read_max_uid_value(session);
632
633 return MAIL_NO_ERROR;
634
635 free:
636 free(quoted_mb);
637 err:
638 return res;
639}
640
641static int mhdriver_cached_expunge_folder(mailsession * session)
642{
643 struct mailmh_folder * folder;
644 int res;
645 char filename_flags[PATH_MAX];
646 struct mail_cache_db * cache_db_flags;
647 MMAPString * mmapstr;
648 struct mh_cached_session_state_data * cached_data;
649 unsigned int i;
650 int r;
651
652 cached_data = get_cached_data(session);
653 if (cached_data->mh_quoted_mb == NULL) {
654 res = MAIL_ERROR_BAD_STATE;
655 goto err;
656 }
657
658 mh_flags_store_process(cached_data->mh_flags_directory,
659 cached_data->mh_quoted_mb,
660 cached_data->mh_flags_store);
661
662 folder = get_mh_cur_folder(session);
663 if (folder == NULL) {
664 res = MAIL_ERROR_BAD_STATE;
665 goto err;
666 }
667
668 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
669 cached_data->mh_flags_directory, cached_data->mh_quoted_mb, FLAGS_NAME);
670
671 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
672 if (r < 0) {
673 res = MAIL_ERROR_FILE;
674 goto err;
675 }
676
677 mmapstr = mmap_string_new("");
678 if (mmapstr == NULL) {
679 res = MAIL_ERROR_MEMORY;
680 goto close_db_flags;
681 }
682
683 for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) {
684 struct mailmh_msg_info * mh_info;
685 struct mail_flags * flags;
686
687 mh_info = carray_get(folder->fl_msgs_tab, i);
688 if (mh_info == NULL)
689 continue;
690
691 r = mhdriver_get_cached_flags(cache_db_flags, mmapstr,
692 session, mh_info->msg_index, &flags);
693 if (r != MAIL_NO_ERROR)
694 continue;
695
696 if (flags->fl_flags & MAIL_FLAG_DELETED) {
697 r = mailmh_folder_remove_message(folder, mh_info->msg_index);
698 }
699
700 mail_flags_free(flags);
701 }
702
703 mmap_string_free(mmapstr);
704 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
705
706 mailmh_folder_update(folder);
707
708 return MAIL_NO_ERROR;
709
710 close_db_flags:
711 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
712 err:
713 return res;
714}
715
716
717static int mhdriver_cached_status_folder(mailsession * session, char * mb,
718 uint32_t * result_messages,
719 uint32_t * result_recent,
720 uint32_t * result_unseen)
721{
722 struct mailmh_folder * folder;
723 int res;
724 char filename_flags[PATH_MAX];
725 struct mail_cache_db * cache_db_flags;
726 MMAPString * mmapstr;
727 struct mh_cached_session_state_data * cached_data;
728 unsigned int i;
729 int r;
730 uint32_t count;
731 uint32_t recent;
732 uint32_t unseen;
733
734 r = mhdriver_cached_select_folder(session, mb);
735 if (r != MAIL_NO_ERROR) {
736 res = r;
737 goto err;
738 }
739
740 count = 0;
741 recent = 0;
742 unseen = 0;
743
744 folder = get_mh_cur_folder(session);
745 if (folder == NULL) {
746 res = MAIL_ERROR_BAD_STATE;
747 goto err;
748 }
749
750 cached_data = get_cached_data(session);
751 if (cached_data->mh_quoted_mb == NULL) {
752 res = MAIL_ERROR_BAD_STATE;
753 goto err;
754 }
755
756 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
757 cached_data->mh_flags_directory,
758 cached_data->mh_quoted_mb, FLAGS_NAME);
759
760 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
761 if (r < 0) {
762 res = MAIL_ERROR_FILE;
763 goto err;
764 }
765
766 mmapstr = mmap_string_new("");
767 if (mmapstr == NULL) {
768 res = MAIL_ERROR_MEMORY;
769 goto close_db_flags;
770 }
771
772 for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) {
773 struct mailmh_msg_info * mh_info;
774 struct mail_flags * flags;
775
776 mh_info = carray_get(folder->fl_msgs_tab, i);
777 if (mh_info == NULL)
778 continue;
779
780 count ++;
781
782 r = mhdriver_get_cached_flags(cache_db_flags, mmapstr,
783 session, mh_info->msg_index,
784 &flags);
785
786 if (r != MAIL_NO_ERROR) {
787 recent ++;
788 unseen ++;
789 continue;
790 }
791
792 if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) {
793 recent ++;
794 }
795 if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) {
796 unseen ++;
797 }
798 mail_flags_free(flags);
799 }
800
801 mmap_string_free(mmapstr);
802 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
803
804 * result_messages = count;
805 * result_recent = recent;
806 * result_unseen = unseen;
807
808 return MAIL_NO_ERROR;
809
810 close_db_flags:
811 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
812 err:
813 return res;
814}
815
816static int mhdriver_cached_messages_number(mailsession * session, char * mb,
817 uint32_t * result)
818{
819 return mailsession_messages_number(get_ancestor(session), mb, result);
820}
821
822static int mhdriver_cached_recent_number(mailsession * session, char * mb,
823 uint32_t * result)
824{
825 uint32_t messages;
826 uint32_t recent;
827 uint32_t unseen;
828 int r;
829
830 r = mhdriver_cached_status_folder(session, mb, &messages, &recent, &unseen);
831 if (r != MAIL_NO_ERROR)
832 return r;
833
834 * result = recent;
835
836 return MAIL_NO_ERROR;
837}
838
839
840static int mhdriver_cached_unseen_number(mailsession * session, char * mb,
841 uint32_t * result)
842{
843 uint32_t messages;
844 uint32_t recent;
845 uint32_t unseen;
846 int r;
847
848 r = mhdriver_cached_status_folder(session, mb, &messages, &recent, &unseen);
849 if (r != MAIL_NO_ERROR)
850 return r;
851
852 * result = recent;
853
854 return MAIL_NO_ERROR;
855}
856
857
858static int mhdriver_cached_list_folders(mailsession * session, char * mb,
859 struct mail_list ** result)
860{
861 return mailsession_list_folders(get_ancestor(session), mb, result);
862}
863
864static int mhdriver_cached_lsub_folders(mailsession * session, char * mb,
865 struct mail_list ** result)
866{
867 return mailsession_lsub_folders(get_ancestor(session), mb, result);
868}
869
870static int mhdriver_cached_subscribe_folder(mailsession * session, char * mb)
871{
872 return mailsession_subscribe_folder(get_ancestor(session), mb);
873}
874
875static int mhdriver_cached_unsubscribe_folder(mailsession * session,
876 char * mb)
877{
878 return mailsession_unsubscribe_folder(get_ancestor(session), mb);
879}
880
881/* messages operations */
882
883static int mhdriver_cached_append_message(mailsession * session,
884 char * message, size_t size)
885{
886 return mailsession_append_message(get_ancestor(session), message, size);
887}
888
889static int mhdriver_cached_copy_message(mailsession * session,
890 uint32_t num, char * mb)
891{
892 return mailsession_copy_message(get_ancestor(session), num, mb);
893}
894
895static int mhdriver_cached_remove_message(mailsession * session, uint32_t num)
896{
897 return mailsession_remove_message(get_ancestor(session), num);
898}
899
900static int mhdriver_cached_move_message(mailsession * session,
901 uint32_t num, char * mb)
902{
903 return mailsession_move_message(get_ancestor(session), num, mb);
904}
905
906static int
907mhdriver_cached_get_messages_list(mailsession * session,
908 struct mailmessage_list ** result)
909{
910 struct mailmh_folder * folder;
911 int res;
912
913 folder = get_mh_cur_folder(session);
914 if (folder == NULL) {
915 res = MAIL_ERROR_BAD_STATE;
916 goto err;
917 }
918
919 return mh_get_messages_list(folder, session,
920 mh_cached_message_driver, result);
921
922 err:
923 return res;
924}
925
926
927
928static int
929get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
930 mailsession * session, uint32_t num,
931 struct mailimf_fields ** result)
932{
933 int r;
934 char keyname[PATH_MAX];
935 struct mailimf_fields * fields;
936 int res;
937 struct mailmh_folder * folder;
938 struct mailmh_msg_info * msg_info;
939 chashdatum key;
940 chashdatum data;
941
942 folder = get_mh_cur_folder(session);
943
944#if 0
945 msg_info = cinthash_find(mh_data->mh_cur_folder->fl_msgs_hash, num);
946 if (msg_info == NULL)
947 return MAIL_ERROR_CACHE_MISS;
948#endif
949 key.data = &num;
950 key.len = sizeof(num);
951 r = chash_get(folder->fl_msgs_hash, &key, &data);
952 if (r < 0)
953 return MAIL_ERROR_CACHE_MISS;
954 msg_info = data.data;
955
956 snprintf(keyname, PATH_MAX, "%u-%u-%u-envelope",
957 num, (uint32_t) msg_info->msg_mtime, msg_info->msg_size);
958
959 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields);
960 if (r != MAIL_NO_ERROR) {
961 res = r;
962 goto err;
963 }
964
965 * result = fields;
966
967 return MAIL_NO_ERROR;
968
969 err:
970 return res;
971}
972
973static int
974write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
975 mailsession * session, uint32_t num,
976 struct mailimf_fields * fields)
977{
978 int r;
979 char keyname[PATH_MAX];
980 int res;
981 struct mailmh_folder * folder;
982 chashdatum key;
983 chashdatum data;
984 struct mailmh_msg_info * msg_info;
985
986 folder = get_mh_cur_folder(session);
987#if 0
988 msg_info = cinthash_find(mh_data->mh_cur_folder->fl_msgs_hash, num);
989 if (msg_info == NULL) {
990 res = MAIL_ERROR_CACHE_MISS;
991 goto err;
992 }
993#endif
994 key.data = &num;
995 key.len = sizeof(num);
996 r = chash_get(folder->fl_msgs_hash, &key, &data);
997 if (r < 0)
998 return MAIL_ERROR_CACHE_MISS;
999 msg_info = data.data;
1000
1001 snprintf(keyname, PATH_MAX, "%u-%u-%u-envelope",
1002 num, (uint32_t) msg_info->msg_mtime, msg_info->msg_size);
1003
1004 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields);
1005 if (r != MAIL_NO_ERROR) {
1006 res = r;
1007 goto err;
1008 }
1009
1010 return MAIL_NO_ERROR;
1011
1012 err:
1013 return res;
1014}
1015
1016static int
1017mhdriver_cached_get_envelopes_list(mailsession * session,
1018 struct mailmessage_list * env_list)
1019{
1020 int r;
1021 unsigned int i;
1022 char filename_env[PATH_MAX];
1023 char filename_flags[PATH_MAX];
1024 struct mail_cache_db * cache_db_env;
1025 struct mail_cache_db * cache_db_flags;
1026 MMAPString * mmapstr;
1027 int res;
1028 struct mh_cached_session_state_data * cached_data;
1029
1030 cached_data = get_cached_data(session);
1031 if (cached_data->mh_quoted_mb == NULL) {
1032 res = MAIL_ERROR_BAD_STATE;
1033 goto err;
1034 }
1035
1036 mh_flags_store_process(cached_data->mh_flags_directory,
1037 cached_data->mh_quoted_mb,
1038 cached_data->mh_flags_store);
1039
1040 mmapstr = mmap_string_new("");
1041 if (mmapstr == NULL) {
1042 res = MAIL_ERROR_MEMORY;
1043 goto err;
1044 }
1045
1046 snprintf(filename_env, PATH_MAX, "%s/%s/%s",
1047 cached_data->mh_cache_directory,
1048 cached_data->mh_quoted_mb, ENV_NAME);
1049
1050 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
1051 if (r < 0) {
1052 res = MAIL_ERROR_MEMORY;
1053 goto free_mmapstr;
1054 }
1055
1056 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
1057 cached_data->mh_flags_directory, cached_data->mh_quoted_mb, FLAGS_NAME);
1058
1059 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
1060 if (r < 0) {
1061 res = MAIL_ERROR_MEMORY;
1062 goto close_db_env;
1063 }
1064
1065 /* fill with cached */
1066
1067 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1068 mailmessage * msg;
1069 struct mailimf_fields * fields;
1070 struct mail_flags * flags;
1071
1072 msg = carray_get(env_list->msg_tab, i);
1073
1074 if (msg->msg_fields == NULL) {
1075 r = get_cached_envelope(cache_db_env, mmapstr,
1076 msg->msg_session, msg->msg_index, &fields);
1077 if (r == MAIL_NO_ERROR) {
1078 msg->msg_cached = TRUE;
1079 msg->msg_fields = fields;
1080 }
1081 }
1082
1083 if (msg->msg_flags == NULL) {
1084 r = mhdriver_get_cached_flags(cache_db_flags, mmapstr,
1085 session, msg->msg_index, &flags);
1086 if (r == MAIL_NO_ERROR) {
1087 msg->msg_flags = flags;
1088 }
1089 }
1090 }
1091
1092 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
1093 mail_cache_db_close_unlock(filename_env, cache_db_env);
1094
1095 r = mailsession_get_envelopes_list(get_ancestor(session), env_list);
1096
1097 if (r != MAIL_NO_ERROR) {
1098 res = r;
1099 goto free_mmapstr;
1100 }
1101
1102 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
1103 if (r < 0) {
1104 res = MAIL_ERROR_MEMORY;
1105 goto free_mmapstr;
1106 }
1107
1108 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
1109 if (r < 0) {
1110 res = MAIL_ERROR_MEMORY;
1111 goto close_db_env;
1112 }
1113
1114 /* add flags */
1115
1116 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1117 mailmessage * msg;
1118
1119 msg = carray_get(env_list->msg_tab, i);
1120
1121 if (msg->msg_flags == NULL)
1122 msg->msg_flags = mail_flags_new_empty();
1123 }
1124
1125 /* must write cache */
1126
1127 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
1128 mailmessage * msg;
1129
1130 msg = carray_get(env_list->msg_tab, i);
1131
1132 if (msg->msg_fields != NULL) {
1133 if (!msg->msg_cached) {
1134 r = write_cached_envelope(cache_db_env, mmapstr,
1135 session, msg->msg_index, msg->msg_fields);
1136 }
1137 }
1138
1139 if (msg->msg_flags != NULL) {
1140 r = mhdriver_write_cached_flags(cache_db_flags, mmapstr,
1141 msg->msg_uid, msg->msg_flags);
1142 }
1143 }
1144
1145 /* flush cache */
1146
1147 maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list);
1148
1149 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
1150 mail_cache_db_close_unlock(filename_env, cache_db_env);
1151
1152 mmap_string_free(mmapstr);
1153
1154 return MAIL_NO_ERROR;
1155
1156 close_db_env:
1157 mail_cache_db_close_unlock(filename_env, cache_db_env);
1158 free_mmapstr:
1159 mmap_string_free(mmapstr);
1160 err:
1161 return res;
1162}
1163
1164static int mhdriver_cached_get_message(mailsession * session,
1165 uint32_t num, mailmessage ** result)
1166{
1167 mailmessage * msg_info;
1168 int r;
1169
1170 msg_info = mailmessage_new();
1171 if (msg_info == NULL)
1172 return MAIL_ERROR_MEMORY;
1173
1174 r = mailmessage_init(msg_info, session, mh_cached_message_driver, num, 0);
1175 if (r != MAIL_NO_ERROR)
1176 return r;
1177
1178 * result = msg_info;
1179
1180 return MAIL_NO_ERROR;
1181}
1182
1183static int mhdriver_cached_get_message_by_uid(mailsession * session,
1184 const char * uid,
1185 mailmessage ** result)
1186{
1187 uint32_t index;
1188 char *p;
1189 struct mailmh_msg_info * mh_msg_info;
1190 struct mailmh_folder * folder;
1191 time_t mtime;
1192 char * mtime_p;
1193 chashdatum key;
1194 chashdatum data;
1195 int r;
1196
1197 if (uid == NULL)
1198 return MAIL_ERROR_INVAL;
1199
1200 index = strtoul(uid, &p, 10);
1201 if (p == uid || * p != '-')
1202 return MAIL_ERROR_INVAL;
1203
1204 folder = get_mh_cur_folder(session);
1205
1206 mh_msg_info = NULL;
1207 key.data = &index;
1208 key.len = sizeof(index);
1209 r = chash_get(folder->fl_msgs_hash, &key, &data);
1210 if (r < 0)
1211 return MAIL_ERROR_MSG_NOT_FOUND;
1212
1213 mh_msg_info = data.data;
1214
1215 mtime_p = p + 1;
1216
1217 mtime = strtoul(mtime_p, &p, 10);
1218 if ((* p == '-') && (mtime == mh_msg_info->msg_mtime)) {
1219 size_t size;
1220 char *size_p;
1221
1222 size_p = p + 1;
1223 size = strtoul(size_p, &p, 10);
1224 if ((* p == '\0') && (size == mh_msg_info->msg_size))
1225 return mhdriver_cached_get_message(session, index, result);
1226 }
1227 else if (*p != '-') {
1228 return MAIL_ERROR_INVAL;
1229 }
1230
1231 return MAIL_ERROR_MSG_NOT_FOUND;
1232}
diff --git a/kmicromail/libetpan/generic/mhdriver_cached.h b/kmicromail/libetpan/generic/mhdriver_cached.h
new file mode 100644
index 0000000..4a07e7d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_cached.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MHDRIVER_CACHED_H
37
38#define MHDRIVER_CACHED_H
39
40#include <libetpan/mhdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * mh_cached_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/mhdriver_cached_message.c b/kmicromail/libetpan/generic/mhdriver_cached_message.c
new file mode 100644
index 0000000..f716fb9
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_cached_message.c
@@ -0,0 +1,338 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mhdriver_message.h"
37
38#include "mailmessage_tools.h"
39#include "mhdriver_tools.h"
40#include "mhdriver_cached.h"
41#include "mailmh.h"
42#include "generic_cache.h"
43
44#include "mail_cache_db.h"
45
46#include <unistd.h>
47#include <sys/mman.h>
48#include <sys/types.h>
49#include <sys/stat.h>
50#include <fcntl.h>
51#include <string.h>
52#include <stdlib.h>
53
54static int mh_prefetch(mailmessage * msg_info);
55
56static void mh_prefetch_free(struct generic_message_t * msg);
57
58static int mh_initialize(mailmessage * msg_info);
59
60static int mh_fetch_size(mailmessage * msg_info,
61 size_t * result);
62
63static int mh_get_flags(mailmessage * msg_info,
64 struct mail_flags ** result);
65
66static void mh_uninitialize(mailmessage * msg_info);
67
68static void mh_flush(mailmessage * msg_info);
69
70static void mh_check(mailmessage * msg_info);
71
72static int mh_fetch_header(mailmessage * msg_info,
73 char ** result,
74 size_t * result_len);
75
76static mailmessage_driver local_mh_cached_message_driver = {
77 .msg_name = "mh-cached",
78
79 .msg_initialize = mh_initialize,
80 .msg_uninitialize = mh_uninitialize,
81
82 .msg_flush = mh_flush,
83 .msg_check = mh_check,
84
85 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
86
87 .msg_fetch = mailmessage_generic_fetch,
88 .msg_fetch_header = mh_fetch_header,
89 .msg_fetch_body = mailmessage_generic_fetch_body,
90 .msg_fetch_size = mh_fetch_size,
91 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
92 .msg_fetch_section = mailmessage_generic_fetch_section,
93 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
94 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
95 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
96 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
97
98 .msg_get_flags = mh_get_flags,
99};
100
101mailmessage_driver * mh_cached_message_driver =
102&local_mh_cached_message_driver;
103
104static inline struct mh_cached_session_state_data *
105get_cached_session_data(mailmessage * msg)
106{
107 return msg->msg_session->sess_data;
108}
109
110static inline mailsession * get_ancestor_session(mailmessage * msg)
111{
112 return get_cached_session_data(msg)->mh_ancestor;
113}
114
115static inline struct mh_session_state_data *
116get_ancestor_session_data(mailmessage * msg)
117{
118 return get_ancestor_session(msg)->sess_data;
119}
120
121static inline struct mailmh *
122get_mh_session(mailmessage * msg)
123{
124 return get_ancestor_session_data(msg)->mh_session;
125}
126
127static inline struct mailmh_folder *
128get_mh_cur_folder(mailmessage * msg)
129{
130 return get_ancestor_session_data(msg)->mh_cur_folder;
131}
132
133static int mh_prefetch(mailmessage * msg_info)
134{
135 struct generic_message_t * msg;
136 int r;
137 char * msg_content;
138 size_t msg_length;
139
140 r = mhdriver_fetch_message(get_ancestor_session(msg_info),
141 msg_info->msg_index, &msg_content, &msg_length);
142 if (r != MAIL_NO_ERROR)
143 return r;
144
145 msg = msg_info->msg_data;
146
147 msg->msg_message = msg_content;
148 msg->msg_length = msg_length;
149
150 return MAIL_NO_ERROR;
151}
152
153static void mh_prefetch_free(struct generic_message_t * msg)
154{
155 if (msg->msg_message != NULL) {
156 mmap_string_unref(msg->msg_message);
157 msg->msg_message = NULL;
158 }
159}
160
161static int mh_initialize(mailmessage * msg_info)
162{
163 struct generic_message_t * msg;
164 int r;
165 char * uid;
166 char static_uid[PATH_MAX];
167 struct mailmh_msg_info * mh_msg_info;
168 chashdatum key;
169 chashdatum data;
170 struct mailmh_folder * folder;
171
172 folder = get_mh_cur_folder(msg_info);
173
174 key.data = &msg_info->msg_index;
175 key.len = sizeof(msg_info->msg_index);
176 r = chash_get(folder->fl_msgs_hash, &key, &data);
177 if (r < 0)
178 return MAIL_ERROR_INVAL;
179
180 mh_msg_info = data.data;
181
182 snprintf(static_uid, PATH_MAX, "%u-%lu-%u", msg_info->msg_index,
183 mh_msg_info->msg_mtime, mh_msg_info->msg_size);
184 uid = strdup(static_uid);
185 if (uid == NULL)
186 return MAIL_ERROR_MEMORY;
187
188 r = mailmessage_generic_initialize(msg_info);
189 if (r != MAIL_NO_ERROR) {
190 free(uid);
191 return r;
192 }
193
194 msg = msg_info->msg_data;
195 msg->msg_prefetch = mh_prefetch;
196 msg->msg_prefetch_free = mh_prefetch_free;
197 msg_info->msg_uid = uid;
198
199 return MAIL_NO_ERROR;
200}
201
202static void mh_uninitialize(mailmessage * msg_info)
203{
204 mailmessage_generic_uninitialize(msg_info);
205}
206
207
208#define FLAGS_NAME "flags.db"
209
210static void mh_flush(mailmessage * msg_info)
211{
212 mailmessage_generic_flush(msg_info);
213}
214
215static void mh_check(mailmessage * msg_info)
216{
217 int r;
218
219 if (msg_info->msg_flags != NULL) {
220 r = mail_flags_store_set(get_cached_session_data(msg_info)->mh_flags_store,
221 msg_info);
222 /* ignore errors */
223 }
224}
225
226static int mh_fetch_size(mailmessage * msg_info,
227 size_t * result)
228{
229 int r;
230 size_t size;
231
232 r = mhdriver_fetch_size(get_ancestor_session(msg_info),
233 msg_info->msg_index, &size);
234 if (r != MAIL_NO_ERROR)
235 return r;
236
237 * result = size;
238
239 return MAIL_NO_ERROR;
240}
241
242static int mh_get_flags(mailmessage * msg_info,
243 struct mail_flags ** result)
244{
245 int r;
246 struct mail_flags * flags;
247 struct mail_cache_db * cache_db_flags;
248 char filename_flags[PATH_MAX];
249 int res;
250 struct mh_cached_session_state_data * cached_data;
251 MMAPString * mmapstr;
252
253 if (msg_info->msg_flags != NULL) {
254 * result = msg_info->msg_flags;
255
256 return MAIL_NO_ERROR;
257 }
258
259 cached_data = get_cached_session_data(msg_info);
260
261 flags = mail_flags_store_get(cached_data->mh_flags_store,
262 msg_info->msg_index);
263
264 if (flags == NULL) {
265 if (cached_data->mh_quoted_mb == NULL) {
266 res = MAIL_ERROR_BAD_STATE;
267 goto err;
268 }
269
270 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
271 cached_data->mh_flags_directory,
272 cached_data->mh_quoted_mb, FLAGS_NAME);
273
274 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
275 if (r < 0) {
276 res = MAIL_ERROR_MEMORY;
277 goto err;
278 }
279
280 mmapstr = mmap_string_new("");
281 if (mmapstr == NULL) {
282 res = MAIL_ERROR_MEMORY;
283 goto close_db_flags;
284 }
285
286 r = mhdriver_get_cached_flags(cache_db_flags, mmapstr,
287 msg_info->msg_session, msg_info->msg_index, &flags);
288 if (r != MAIL_NO_ERROR) {
289 flags = mail_flags_new_empty();
290 if (flags == NULL) {
291 res = MAIL_ERROR_MEMORY;
292 goto free_mmapstr;
293 }
294 }
295
296 mmap_string_free(mmapstr);
297 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
298 }
299
300 msg_info->msg_flags = flags;
301
302 * result = flags;
303
304 return MAIL_NO_ERROR;
305
306 free_mmapstr:
307 mmap_string_free(mmapstr);
308 close_db_flags:
309 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
310 err:
311 return res;
312}
313
314static int mh_fetch_header(mailmessage * msg_info,
315 char ** result,
316 size_t * result_len)
317{
318 struct generic_message_t * msg;
319 int r;
320 char * msg_content;
321 size_t msg_length;
322
323 msg = msg_info->msg_data;
324 if (msg->msg_message != NULL) {
325 return mailmessage_generic_fetch_header(msg_info, result, result_len);
326 }
327 else {
328 r = mhdriver_fetch_header(get_ancestor_session(msg_info),
329 msg_info->msg_index, &msg_content, &msg_length);
330 if (r != MAIL_NO_ERROR)
331 return r;
332
333 * result = msg_content;
334 * result_len = msg_length;
335
336 return MAIL_NO_ERROR;
337 }
338}
diff --git a/kmicromail/libetpan/generic/mhdriver_cached_message.h b/kmicromail/libetpan/generic/mhdriver_cached_message.h
new file mode 100644
index 0000000..f3ed089
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_cached_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MHDRIVER_CACHED_MESSAGE_H
37
38#define MHDRIVER_CACHED_MESSAGE_H
39
40#include <libetpan/mhdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * mh_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/mhdriver_message.c b/kmicromail/libetpan/generic/mhdriver_message.c
new file mode 100644
index 0000000..2c023e7
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_message.c
@@ -0,0 +1,212 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mhdriver_message.h"
37
38#include "mailmessage_tools.h"
39#include "mhdriver_tools.h"
40#include "mhdriver.h"
41#include "mailmh.h"
42
43#include <unistd.h>
44#include <sys/mman.h>
45#include <sys/types.h>
46#include <sys/stat.h>
47#include <fcntl.h>
48#include <string.h>
49#include <stdlib.h>
50
51static int mh_prefetch(mailmessage * msg_info);
52
53static void mh_prefetch_free(struct generic_message_t * msg);
54
55static int mh_initialize(mailmessage * msg_info);
56
57static int mh_fetch_size(mailmessage * msg_info,
58 size_t * result);
59
60static int mh_fetch_header(mailmessage * msg_info,
61 char ** result,
62 size_t * result_len);
63
64static mailmessage_driver local_mh_message_driver = {
65 .msg_name = "mh",
66
67 .msg_initialize = mh_initialize,
68 .msg_uninitialize = mailmessage_generic_uninitialize,
69
70 .msg_flush = mailmessage_generic_flush,
71 .msg_check = NULL,
72
73 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
74
75 .msg_fetch = mailmessage_generic_fetch,
76 .msg_fetch_header = mh_fetch_header,
77 .msg_fetch_body = mailmessage_generic_fetch_body,
78 .msg_fetch_size = mh_fetch_size,
79 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
80 .msg_fetch_section = mailmessage_generic_fetch_section,
81 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
82 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
83 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
84 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
85
86 .msg_get_flags = NULL,
87};
88
89mailmessage_driver * mh_message_driver = &local_mh_message_driver;
90
91static int mh_prefetch(mailmessage * msg_info)
92{
93 struct generic_message_t * msg;
94 int r;
95 char * msg_content;
96 size_t msg_length;
97
98 r = mhdriver_fetch_message(msg_info->msg_session, msg_info->msg_index,
99 &msg_content, &msg_length);
100 if (r != MAIL_NO_ERROR)
101 return r;
102
103 msg = msg_info->msg_data;
104
105 msg->msg_message = msg_content;
106 msg->msg_length = msg_length;
107
108 return MAIL_NO_ERROR;
109}
110
111static void mh_prefetch_free(struct generic_message_t * msg)
112{
113 if (msg->msg_message != NULL) {
114 mmap_string_unref(msg->msg_message);
115 msg->msg_message = NULL;
116 }
117}
118
119static inline struct mh_session_state_data * get_data(mailmessage * msg)
120{
121 return msg->msg_session->sess_data;
122}
123
124static inline struct mailmh_folder * get_mh_cur_folder(mailmessage * msg)
125{
126 return get_data(msg)->mh_cur_folder;
127}
128
129static int mh_initialize(mailmessage * msg_info)
130{
131 struct generic_message_t * msg;
132 int r;
133 char * uid;
134 char static_uid[PATH_MAX];
135 struct mailmh_msg_info * mh_msg_info;
136 chashdatum key;
137 chashdatum value;
138
139 key.data = &msg_info->msg_index;
140 key.len = sizeof(msg_info->msg_index);
141 r = chash_get(get_mh_cur_folder(msg_info)->fl_msgs_hash, &key, &value);
142 if (r < 0)
143 return MAIL_ERROR_INVAL;
144
145 mh_msg_info = value.data;
146
147 snprintf(static_uid, PATH_MAX, "%u-%lu-%u", msg_info->msg_index,
148 mh_msg_info->msg_mtime, mh_msg_info->msg_size);
149 uid = strdup(static_uid);
150 if (uid == NULL)
151 return MAIL_ERROR_MEMORY;
152
153 r = mailmessage_generic_initialize(msg_info);
154 if (r != MAIL_NO_ERROR) {
155 free(uid);
156 return r;
157 }
158
159 msg = msg_info->msg_data;
160 msg->msg_prefetch = mh_prefetch;
161 msg->msg_prefetch_free = mh_prefetch_free;
162 msg_info->msg_uid = uid;
163
164 return MAIL_NO_ERROR;
165}
166
167
168static int mh_fetch_size(mailmessage * msg_info,
169 size_t * result)
170{
171 int r;
172 size_t size;
173
174 r = mhdriver_fetch_size(msg_info->msg_session, msg_info->msg_index, &size);
175 if (r != MAIL_NO_ERROR)
176 return r;
177
178 * result = size;
179
180 return MAIL_NO_ERROR;
181}
182
183
184
185
186static int mh_fetch_header(mailmessage * msg_info,
187 char ** result,
188 size_t * result_len)
189{
190 struct generic_message_t * msg;
191 int r;
192 char * msg_content;
193 size_t msg_length;
194
195 msg = msg_info->msg_data;
196 if (msg->msg_message != NULL) {
197
198 r = mailmessage_generic_fetch_header(msg_info, result, result_len);
199 return r;
200 }
201 else {
202 r = mhdriver_fetch_header(msg_info->msg_session, msg_info->msg_index,
203 &msg_content, &msg_length);
204 if (r != MAIL_NO_ERROR)
205 return r;
206
207 * result = msg_content;
208 * result_len = msg_length;
209
210 return MAIL_NO_ERROR;
211 }
212}
diff --git a/kmicromail/libetpan/generic/mhdriver_message.h b/kmicromail/libetpan/generic/mhdriver_message.h
new file mode 100644
index 0000000..a7cb2cf
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MHDRIVER_MESSAGE_H
37
38#define MHDRIVER_MESSAGE_H
39
40#include <libetpan/mhdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * mh_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/mhdriver_tools.c b/kmicromail/libetpan/generic/mhdriver_tools.c
new file mode 100644
index 0000000..cb863fa
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_tools.c
@@ -0,0 +1,475 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mhdriver_tools.h"
37
38#include "mailmessage.h"
39#include "mhdriver.h"
40#include "mhdriver_cached.h"
41#include "maildriver_types.h"
42#include "mailmh.h"
43#include "generic_cache.h"
44#include "imfcache.h"
45#include "mail_cache_db.h"
46
47#include <unistd.h>
48#include <sys/mman.h>
49#include <sys/types.h>
50#include <sys/stat.h>
51#include <fcntl.h>
52#include <string.h>
53#include <stdlib.h>
54
55int mhdriver_mh_error_to_mail_error(int error)
56{
57 switch (error) {
58 case MAILMH_NO_ERROR:
59 return MAIL_NO_ERROR;
60
61 case MAILMH_ERROR_FOLDER:
62 return MAIL_NO_ERROR;
63
64 case MAILMH_ERROR_MEMORY:
65 return MAIL_ERROR_MEMORY;
66
67 case MAILMH_ERROR_FILE:
68 return MAIL_ERROR_FILE;
69
70 case MAILMH_ERROR_COULD_NOT_ALLOC_MSG:
71 return MAIL_ERROR_APPEND;
72
73 case MAILMH_ERROR_RENAME:
74 return MAIL_ERROR_RENAME;
75
76 case MAILMH_ERROR_MSG_NOT_FOUND:
77 return MAIL_ERROR_MSG_NOT_FOUND;
78
79 default:
80 return MAIL_ERROR_INVAL;
81 }
82}
83
84
85static inline struct mh_session_state_data * get_data(mailsession * session)
86{
87 return session->sess_data;
88}
89
90static inline struct mailmh_folder * get_mh_cur_folder(mailsession * session)
91{
92 return get_data(session)->mh_cur_folder;
93}
94
95static inline struct mh_cached_session_state_data *
96cached_get_data(mailsession * session)
97{
98 return session->sess_data;
99}
100
101
102static inline mailsession * cached_get_ancestor(mailsession * session)
103{
104 return cached_get_data(session)->mh_ancestor;
105}
106
107static inline struct mh_session_state_data *
108cached_get_ancestor_data(mailsession * session)
109{
110 return get_data(cached_get_ancestor(session));
111}
112
113static inline struct mailmh_folder *
114cached_get_mh_cur_folder(mailsession * session)
115{
116 return get_mh_cur_folder(cached_get_ancestor(session));
117}
118
119int mhdriver_fetch_message(mailsession * session, uint32_t index,
120 char ** result, size_t * result_len)
121{
122 size_t size;
123 size_t cur_token;
124 struct mailmh_folder * folder;
125 int fd;
126 MMAPString * mmapstr;
127 char * str;
128 int res;
129 int r;
130
131 folder = get_mh_cur_folder(session);
132 if (folder == NULL) {
133 res = MAIL_ERROR_BAD_STATE;
134 goto err;
135 }
136
137 r = mailmh_folder_get_message_fd(folder, index, O_RDONLY, &fd);
138
139 switch (r) {
140 case MAILMH_NO_ERROR:
141 break;
142
143 default:
144 res = mhdriver_mh_error_to_mail_error(r);
145 goto close;
146 }
147
148 r = mhdriver_fetch_size(session, index, &size);
149
150 switch (r) {
151 case MAILMH_NO_ERROR:
152 break;
153
154 default:
155 res = mhdriver_mh_error_to_mail_error(r);
156 goto close;
157 }
158
159 str = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
160 if (str == MAP_FAILED) {
161 res = MAIL_ERROR_FETCH;
162 goto close;
163 }
164
165 /* strip "From " header for broken implementations */
166 /* XXX - called twice, make a function */
167 cur_token = 0;
168 if (strncmp("From ", str, size) == 0) {
169 cur_token += 5;
170
171 while (str[cur_token] != '\n') {
172 if (cur_token >= size)
173 break;
174 cur_token ++;
175 }
176 }
177
178 mmapstr = mmap_string_new_len(str + cur_token, size - cur_token);
179 if (mmapstr == NULL) {
180 res = MAIL_ERROR_MEMORY;
181 goto unmap;
182 }
183
184 if (mmap_string_ref(mmapstr) != 0) {
185 res = MAIL_ERROR_MEMORY;
186 goto free_str;
187 }
188
189 munmap(str, size);
190 close(fd);
191
192 * result = mmapstr->str;
193 * result_len = mmapstr->len;
194
195 return MAIL_NO_ERROR;
196
197 free_str:
198 mmap_string_free(mmapstr);
199 unmap:
200 munmap(str, size);
201 close:
202 close(fd);
203 err:
204 return res;
205}
206
207
208int mhdriver_fetch_header(mailsession * session, uint32_t index,
209 char ** result, size_t * result_len)
210{
211 size_t size;
212 size_t cur_token;
213 size_t begin;
214 struct mailmh_folder * folder;
215 int fd;
216 MMAPString * mmapstr;
217 char * str;
218 int res;
219 int r;
220
221 folder = get_mh_cur_folder(session);
222 if (folder == NULL) {
223 res = MAIL_ERROR_BAD_STATE;
224 goto err;
225 }
226
227 r = mailmh_folder_get_message_fd(folder, index, O_RDONLY, &fd);
228
229 switch (r) {
230 case MAILMH_NO_ERROR:
231 break;
232
233 default:
234 res = mhdriver_mh_error_to_mail_error(r);
235 goto close;
236 }
237
238 r = mhdriver_fetch_size(session, index, &size);
239
240 switch (r) {
241 case MAILMH_NO_ERROR:
242 break;
243
244 default:
245 res = mhdriver_mh_error_to_mail_error(r);
246 goto close;
247 }
248
249 str = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
250 if (str == MAP_FAILED) {
251 res = MAIL_ERROR_FETCH;
252 goto close;
253 }
254
255 /* strip "From " header for broken implementations */
256 cur_token = 0;
257 if (size > 5) {
258 if (strncmp("From ", str, size) == 0) {
259 cur_token += 5;
260
261 while (str[cur_token] != '\n') {
262 if (cur_token >= size)
263 break;
264 cur_token ++;
265 }
266 }
267 }
268
269 begin = cur_token;
270
271 while (1) {
272 r = mailimf_ignore_field_parse(str, size, &cur_token);
273 if (r == MAILIMF_NO_ERROR) {
274 /* do nothing */
275 }
276 else
277 break;
278 }
279 mailimf_crlf_parse(str, size, &cur_token);
280
281 mmapstr = mmap_string_new_len(str + begin, cur_token - begin);
282 if (mmapstr == NULL) {
283 res = MAIL_ERROR_MEMORY;
284 goto unmap;
285 }
286
287 if (mmap_string_ref(mmapstr) != 0) {
288 res = MAIL_ERROR_MEMORY;
289 goto free_str;
290 }
291
292 munmap(str, size);
293 close(fd);
294
295 * result = mmapstr->str;
296 * result_len = mmapstr->len;
297
298 return MAIL_NO_ERROR;
299
300 free_str:
301 mmap_string_free(mmapstr);
302 unmap:
303 munmap(str, size);
304 close:
305 close(fd);
306 err:
307 return res;
308}
309
310
311int mhdriver_fetch_size(mailsession * session, uint32_t index,
312 size_t * result)
313{
314 struct mailmh_folder * folder;
315 int r;
316 struct stat buf;
317 char * name;
318
319 folder = get_mh_cur_folder(session);
320 if (folder == NULL)
321 return MAIL_ERROR_FETCH;
322
323 r = mailmh_folder_get_message_filename(folder, index, &name);
324
325 switch (r) {
326 case MAILMH_NO_ERROR:
327 break;
328
329 default:
330 return mhdriver_mh_error_to_mail_error(r);
331 }
332
333 r = stat(name, &buf);
334 free(name);
335 if (r == -1)
336 return MAIL_ERROR_FETCH;
337
338 * result = buf.st_size;
339
340 return MAIL_NO_ERROR;
341}
342
343int
344mhdriver_get_cached_flags(struct mail_cache_db * cache_db,
345 MMAPString * mmapstr,
346 mailsession * session,
347 uint32_t num,
348 struct mail_flags ** result)
349{
350 int r;
351 char keyname[PATH_MAX];
352 struct mail_flags * flags;
353 int res;
354 struct mailmh_msg_info * msg_info;
355 chashdatum key;
356 chashdatum data;
357 struct mailmh_folder * folder;
358
359 folder = cached_get_mh_cur_folder(session);
360#if 0
361 msg_info = cinthash_find(mh_data->cur_folder->fl_msgs_hash, num);
362 if (msg_info == NULL)
363 return MAIL_ERROR_CACHE_MISS;
364#endif
365 key.data = &num;
366 key.len = sizeof(num);
367 r = chash_get(folder->fl_msgs_hash, &key, &data);
368 if (r < 0)
369 return MAIL_ERROR_CACHE_MISS;
370 msg_info = data.data;
371
372 snprintf(keyname, PATH_MAX, "%u-%u-%u-flags",
373 num, (uint32_t) msg_info->msg_mtime, msg_info->msg_size);
374
375 r = generic_cache_flags_read(cache_db, mmapstr, keyname, &flags);
376 if (r != MAIL_NO_ERROR) {
377 res = r;
378 goto err;
379 }
380
381 * result = flags;
382
383 return MAIL_NO_ERROR;
384
385 err:
386 return res;
387}
388
389int
390mhdriver_write_cached_flags(struct mail_cache_db * cache_db,
391 MMAPString * mmapstr,
392 char * uid,
393 struct mail_flags * flags)
394{
395 int r;
396 char keyname[PATH_MAX];
397 int res;
398
399 snprintf(keyname, PATH_MAX, "%s-flags", uid);
400
401 r = generic_cache_flags_write(cache_db, mmapstr, keyname, flags);
402 if (r != MAIL_NO_ERROR) {
403 res = r;
404 goto err;
405 }
406
407 return MAIL_NO_ERROR;
408
409 err:
410 return res;
411}
412
413
414int mh_get_messages_list(struct mailmh_folder * folder,
415 mailsession * session, mailmessage_driver * driver,
416 struct mailmessage_list ** result)
417{
418 unsigned int i;
419 struct mailmessage_list * env_list;
420 int r;
421 carray * tab;
422 int res;
423
424 tab = carray_new(128);
425 if (tab == NULL) {
426 res = MAIL_ERROR_MEMORY;
427 goto err;
428 }
429
430 for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) {
431 struct mailmh_msg_info * mh_info;
432 mailmessage * msg;
433
434 mh_info = carray_get(folder->fl_msgs_tab, i);
435 if (mh_info == NULL)
436 continue;
437
438 msg = mailmessage_new();
439 if (msg == NULL) {
440 res = MAIL_ERROR_MEMORY;
441 goto free_list;
442 }
443
444 r = mailmessage_init(msg, session, driver,
445 mh_info->msg_index, mh_info->msg_size);
446 if (r != MAIL_NO_ERROR) {
447 res = r;
448 goto free_list;
449 }
450
451 r = carray_add(tab, msg, NULL);
452 if (r < 0) {
453 mailmessage_free(msg);
454 res = MAIL_ERROR_MEMORY;
455 goto free_list;
456 }
457 }
458
459 env_list = mailmessage_list_new(tab);
460 if (env_list == NULL) {
461 res = MAIL_ERROR_MEMORY;
462 goto free_list;
463 }
464
465 * result = env_list;
466
467 return MAIL_NO_ERROR;
468
469 free_list:
470 for(i = 0 ; i < carray_count(tab) ; i ++)
471 mailmessage_free(carray_get(tab, i));
472 carray_free(tab);
473 err:
474 return res;
475}
diff --git a/kmicromail/libetpan/generic/mhdriver_tools.h b/kmicromail/libetpan/generic/mhdriver_tools.h
new file mode 100644
index 0000000..0d805c1
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_tools.h
@@ -0,0 +1,80 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MHDRIVER_TOOLS_H
37
38#define MHDRIVER_TOOLS_H
39
40#include "maildriver_types.h"
41#include "mail_cache_db_types.h"
42#include "mailmh.h"
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48int mhdriver_mh_error_to_mail_error(int error);
49
50int mhdriver_fetch_message(mailsession * session, uint32_t index,
51 char ** result, size_t * result_len);
52
53int mhdriver_fetch_header(mailsession * session, uint32_t index,
54 char ** result, size_t * result_len);
55
56int mhdriver_fetch_size(mailsession * session, uint32_t index,
57 size_t * result);
58
59int
60mhdriver_get_cached_flags(struct mail_cache_db * cache_db,
61 MMAPString * mmapstr,
62 mailsession * session,
63 uint32_t num,
64 struct mail_flags ** result);
65
66int
67mhdriver_write_cached_flags(struct mail_cache_db * cache_db,
68 MMAPString * mmapstr,
69 char * uid,
70 struct mail_flags * flags);
71
72int mh_get_messages_list(struct mailmh_folder * folder,
73 mailsession * session, mailmessage_driver * driver,
74 struct mailmessage_list ** result);
75
76#ifdef __cplusplus
77}
78#endif
79
80#endif
diff --git a/kmicromail/libetpan/generic/mhdriver_types.h b/kmicromail/libetpan/generic/mhdriver_types.h
new file mode 100644
index 0000000..09c6cc6
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver_types.h
@@ -0,0 +1,100 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MHDRIVER_TYPES_H
37
38#define MHDRIVER_TYPES_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/maildriver_types.h>
43#include <libetpan/mailmh.h>
44#include <libetpan/clist.h>
45#include <libetpan/generic_cache_types.h>
46#include <libetpan/mailstorage_types.h>
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52struct mh_session_state_data {
53 struct mailmh * mh_session;
54
55 struct mailmh_folder * mh_cur_folder;
56
57 clist * mh_subscribed_list;
58};
59
60enum {
61 MHDRIVER_CACHED_SET_CACHE_DIRECTORY = 1,
62 MHDRIVER_CACHED_SET_FLAGS_DIRECTORY,
63};
64
65struct mh_cached_session_state_data {
66 mailsession * mh_ancestor;
67 char * mh_quoted_mb;
68 char mh_cache_directory[PATH_MAX];
69 char mh_flags_directory[PATH_MAX];
70 struct mail_flags_store * mh_flags_store;
71};
72
73/* mh storage */
74
75/*
76 mh_mailstorage is the state data specific to the MH storage.
77
78 - pathname is the root path of the MH storage.
79
80 - cached if this value is != 0, a persistant cache will be
81 stored on local system.
82
83 - cache_directory is the location of the cache.
84
85 - flags_directory is the location of the flags.
86*/
87
88struct mh_mailstorage {
89 char * mh_pathname;
90
91 int mh_cached;
92 char * mh_cache_directory;
93 char * mh_flags_directory;
94};
95
96#ifdef __cplusplus
97}
98#endif
99
100#endif
diff --git a/kmicromail/libetpan/generic/mhstorage.c b/kmicromail/libetpan/generic/mhstorage.c
new file mode 100644
index 0000000..32fc26b
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhstorage.c
@@ -0,0 +1,192 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mhstorage.h"
37
38#include "mhdriver.h"
39#include "mhdriver_cached.h"
40#include "mail.h"
41
42#include <stdlib.h>
43#include <string.h>
44
45/* mh storage */
46
47static int mh_mailstorage_connect(struct mailstorage * storage);
48static int mh_mailstorage_get_folder_session(struct mailstorage * storage,
49 char * pathname, mailsession ** result);
50static void mh_mailstorage_uninitialize(struct mailstorage * storage);
51
52static mailstorage_driver mh_mailstorage_driver = {
53 .sto_name = "mh",
54 .sto_connect = mh_mailstorage_connect,
55 .sto_get_folder_session = mh_mailstorage_get_folder_session,
56 .sto_uninitialize = mh_mailstorage_uninitialize,
57};
58
59int mh_mailstorage_init(struct mailstorage * storage,
60 char * mh_pathname, int mh_cached,
61 char * mh_cache_directory, char * mh_flags_directory)
62{
63 struct mh_mailstorage * mh_storage;
64
65 mh_storage = malloc(sizeof(struct mh_mailstorage));
66 if (mh_storage == NULL)
67 goto err;
68
69 mh_storage->mh_pathname = strdup(mh_pathname);
70 if (mh_storage->mh_pathname == NULL)
71 goto free;
72
73 mh_storage->mh_cached = mh_cached;
74
75 if (mh_cached && (mh_cache_directory != NULL) &&
76 (mh_flags_directory != NULL)) {
77 mh_storage->mh_cache_directory = strdup(mh_cache_directory);
78 if (mh_storage->mh_cache_directory == NULL)
79 goto free_pathname;
80 mh_storage->mh_flags_directory = strdup(mh_flags_directory);
81 if (mh_storage->mh_flags_directory == NULL)
82 goto free_cache_directory;
83 }
84 else {
85 mh_storage->mh_cached = FALSE;
86 mh_storage->mh_cache_directory = NULL;
87 mh_storage->mh_flags_directory = NULL;
88 }
89
90 storage->sto_data = mh_storage;
91 storage->sto_driver = &mh_mailstorage_driver;
92
93 return MAIL_NO_ERROR;
94
95 free_cache_directory:
96 free(mh_storage->mh_cache_directory);
97 free_pathname:
98 free(mh_storage->mh_pathname);
99 free:
100 free(mh_storage);
101 err:
102 return MAIL_ERROR_MEMORY;
103}
104
105static void mh_mailstorage_uninitialize(struct mailstorage * storage)
106{
107 struct mh_mailstorage * mh_storage;
108
109 mh_storage = storage->sto_data;
110 if (mh_storage->mh_flags_directory != NULL)
111 free(mh_storage->mh_flags_directory);
112 if (mh_storage->mh_cache_directory != NULL)
113 free(mh_storage->mh_cache_directory);
114 free(mh_storage->mh_pathname);
115 free(mh_storage);
116
117 storage->sto_data = NULL;
118}
119
120static int mh_mailstorage_connect(struct mailstorage * storage)
121{
122 struct mh_mailstorage * mh_storage;
123 mailsession_driver * driver;
124 int r;
125 int res;
126 mailsession * session;
127
128 mh_storage = storage->sto_data;
129
130 if (mh_storage->mh_cached)
131 driver = mh_cached_session_driver;
132 else
133 driver = mh_session_driver;
134
135 session = mailsession_new(driver);
136 if (session == NULL) {
137 res = MAIL_ERROR_MEMORY;
138 goto err;
139 }
140
141 if (mh_storage->mh_cached) {
142 r = mailsession_parameters(session,
143 MHDRIVER_CACHED_SET_CACHE_DIRECTORY,
144 mh_storage->mh_cache_directory);
145 if (r != MAIL_NO_ERROR) {
146 res = r;
147 goto free;
148 }
149
150 r = mailsession_parameters(session,
151 MHDRIVER_CACHED_SET_FLAGS_DIRECTORY,
152 mh_storage->mh_flags_directory);
153 if (r != MAIL_NO_ERROR) {
154 res = r;
155 goto free;
156 }
157 }
158
159 r = mailsession_connect_path(session, mh_storage->mh_pathname);
160 switch (r) {
161 case MAIL_NO_ERROR_NON_AUTHENTICATED:
162 case MAIL_NO_ERROR_AUTHENTICATED:
163 case MAIL_NO_ERROR:
164 break;
165 default:
166 res = r;
167 goto free;
168 }
169
170 storage->sto_session = session;
171
172 return MAIL_NO_ERROR;
173
174 free:
175 mailsession_free(session);
176 err:
177 return res;
178}
179
180static int mh_mailstorage_get_folder_session(struct mailstorage * storage,
181 char * pathname, mailsession ** result)
182{
183 int r;
184
185 r = mailsession_select_folder(storage->sto_session, pathname);
186 if (r != MAIL_NO_ERROR)
187 return r;
188
189 * result = storage->sto_session;
190
191 return MAIL_NO_ERROR;
192}
diff --git a/kmicromail/libetpan/generic/mhstorage.h b/kmicromail/libetpan/generic/mhstorage.h
new file mode 100644
index 0000000..245bc81
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhstorage.h
@@ -0,0 +1,67 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MHSTORAGE_H
37
38#define MHSTORAGE_H
39
40#include <libetpan/mhdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 mh_mailstorage_init is the constructor for a MH storage
48
49 @param pathname is the filename the root path of the MH storage.
50
51 @param cached if this value is != 0, a persistant cache will be
52 stored on local system.
53
54 @param cache_directory is the location of the cache.
55
56 @param flags_directory is the location of the flags.
57*/
58
59int mh_mailstorage_init(struct mailstorage * storage,
60 char * mh_pathname, int mh_cached,
61 char * mh_cache_directory, char * mh_flags_directory);
62
63#ifdef __cplusplus
64}
65#endif
66
67#endif
diff --git a/kmicromail/libetpan/generic/mime_message_driver.c b/kmicromail/libetpan/generic/mime_message_driver.c
new file mode 100644
index 0000000..273875e
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mime_message_driver.c
@@ -0,0 +1,689 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mime_message_driver.h"
37
38#include "libetpan-config.h"
39
40#include <sys/stat.h>
41#include <sys/types.h>
42#include <unistd.h>
43#include <sys/mman.h>
44#include <stdlib.h>
45#include <string.h>
46
47#include "mailmessage.h"
48#include "mailmessage_tools.h"
49#include "maildriver_tools.h"
50
51static FILE * get_mime_tmp_file(mailmessage * msg,
52 char * filename, size_t size)
53{
54 int fd;
55 mode_t old_mask;
56 FILE * f;
57
58 if (msg->msg_data == NULL)
59 return NULL;
60
61 snprintf(filename, size, "%s/libetpan-mime-XXXXXX",
62 (char *) msg->msg_data);
63
64 old_mask = umask(0077);
65 fd = mkstemp(filename);
66 umask(old_mask);
67 if (fd == -1)
68 return NULL;
69
70 f = fdopen(fd, "r+");
71 if (f == NULL) {
72 close(fd);
73 unlink(filename);
74 }
75
76 return f;
77}
78
79int mime_message_set_tmpdir(mailmessage * msg, char * tmpdir)
80{
81 if (msg->msg_data != NULL)
82 free(msg->msg_data);
83
84 msg->msg_data = strdup(tmpdir);
85 if (msg->msg_data == NULL)
86 return MAIL_ERROR_MEMORY;
87
88 return MAIL_NO_ERROR;
89}
90
91void mime_message_detach_mime(mailmessage * msg)
92{
93 msg->msg_mime = NULL;
94}
95
96mailmessage * mime_message_init(struct mailmime * mime)
97{
98 mailmessage * msg;
99 int r;
100
101 msg = mailmessage_new();
102 if (msg == NULL)
103 goto err;
104
105 r = mailmessage_init(msg, NULL, mime_message_driver, 0, 0);
106 if (r != MAIL_NO_ERROR)
107 goto free;
108
109 if (mime != NULL) {
110 mailmime_free(msg->msg_mime);
111 msg->msg_mime = mime;
112 }
113
114 return msg;
115
116 free:
117 mailmessage_free(msg);
118 err:
119 return NULL;
120}
121
122static int initialize(mailmessage * msg)
123{
124 struct mailmime * mime;
125 int res;
126
127 mime = mailmime_new_message_data(NULL);
128 if (mime == NULL) {
129 res = MAIL_ERROR_MEMORY;
130 goto err;
131 }
132
133 msg->msg_mime = mime;
134
135 return MAIL_NO_ERROR;
136
137 err:
138 return res;
139}
140
141static void uninitialize(mailmessage * msg)
142{
143 /* tmp dir name */
144 if (msg->msg_data != NULL)
145 free(msg->msg_data);
146
147 if (msg->msg_mime != NULL)
148 mailmime_free(msg->msg_mime);
149 msg->msg_mime = NULL;
150}
151
152static void flush(mailmessage * msg)
153{
154 /* do nothing */
155}
156
157static void check(mailmessage * msg)
158{
159 /* do nothing */
160}
161
162static void fetch_result_free(mailmessage * msg_info, char * content)
163{
164 mmap_string_unref(content);
165}
166
167static int file_to_mmapstr(FILE * f,
168 char ** result, size_t * result_len)
169{
170 int fd;
171 char * data;
172 struct stat buf;
173 MMAPString * mmapstr;
174 int res;
175 int r;
176
177 fd = fileno(f);
178 if (fd == -1) {
179 res = MAIL_ERROR_FILE;
180
181 goto err;
182 }
183
184 fflush(f);
185 r = fstat(fd, &buf);
186 if (r == -1) {
187 res = MAIL_ERROR_FILE;
188
189 goto err;
190 }
191
192 data = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
193 if (data == MAP_FAILED) {
194 res = MAIL_ERROR_FILE;
195
196 goto err;
197 }
198
199 mmapstr = mmap_string_new_len(data, buf.st_size);
200 if (mmapstr == NULL) {
201 res = MAIL_ERROR_MEMORY;
202
203 goto unmap;
204 }
205
206 munmap(data, buf.st_size);
207
208 r = mmap_string_ref(mmapstr);
209 if (r != 0) {
210 res = MAIL_ERROR_MEMORY;
211
212 goto err;
213 }
214
215 * result = mmapstr->str;
216 * result_len = mmapstr->len;
217
218 return MAIL_NO_ERROR;
219
220 unmap:
221 munmap(data, buf.st_size);
222 err:
223 return res;
224}
225
226
227static int file_body_to_mmapstr(FILE * f,
228 char ** result, size_t * result_len)
229{
230 int fd;
231 char * data;
232 struct stat buf;
233 MMAPString * mmapstr;
234 size_t cur_token;
235 int res;
236 int r;
237
238 fd = fileno(f);
239 if (fd == -1) {
240 res = MAIL_ERROR_FILE;
241
242 goto err;
243 }
244
245 fflush(f);
246 r = fstat(fd, &buf);
247 if (r == -1) {
248 res = MAIL_ERROR_FILE;
249
250 goto err;
251 }
252
253 data = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
254 if (data == MAP_FAILED) {
255 res = MAIL_ERROR_FILE;
256
257 goto err;
258 }
259
260 cur_token = 0;
261
262 /* skip header */
263
264 while (1) {
265 r = mailimf_ignore_field_parse(data,
266 buf.st_size, &cur_token);
267 if (r == MAILIMF_NO_ERROR) {
268 /* do nothing */
269 }
270 else
271 break;
272 }
273
274 r = mailimf_crlf_parse(data, buf.st_size, &cur_token);
275 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
276 res = maildriver_imf_error_to_mail_error(r);
277 goto unmap;
278 }
279
280 mmapstr = mmap_string_new_len(data + cur_token, buf.st_size - cur_token);
281 if (mmapstr == NULL) {
282 res = MAIL_ERROR_MEMORY;
283
284 goto unmap;
285 }
286
287 munmap(data, buf.st_size);
288
289 r = mmap_string_ref(mmapstr);
290 if (r != 0) {
291 res = MAIL_ERROR_MEMORY;
292
293 goto err;
294 }
295
296 * result = mmapstr->str;
297 * result_len = mmapstr->len;
298
299 return MAIL_NO_ERROR;
300
301 unmap:
302 munmap(data, buf.st_size);
303 err:
304 return res;
305}
306
307static int file_body_body_to_mmapstr(FILE * f,
308 char ** result, size_t * result_len)
309{
310 int fd;
311 char * data;
312 struct stat buf;
313 MMAPString * mmapstr;
314 size_t cur_token;
315 int res;
316 int r;
317
318 fd = fileno(f);
319 if (fd == -1) {
320 res = MAIL_ERROR_FILE;
321
322 goto err;
323 }
324
325 fflush(f);
326 r = fstat(fd, &buf);
327 if (r == -1) {
328 res = MAIL_ERROR_FILE;
329
330 goto err;
331 }
332
333 data = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
334 if (data == MAP_FAILED) {
335 res = MAIL_ERROR_FILE;
336
337 goto err;
338 }
339
340 cur_token = 0;
341
342 /* skip header */
343
344 /* MIME header */
345
346 while (1) {
347 r = mailimf_ignore_field_parse(data,
348 buf.st_size, &cur_token);
349 if (r == MAILIMF_NO_ERROR) {
350 /* do nothing */
351 }
352 else
353 break;
354 }
355
356 r = mailimf_crlf_parse(data, buf.st_size, &cur_token);
357 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
358 res = maildriver_imf_error_to_mail_error(r);
359 goto unmap;
360 }
361
362 /* headers */
363
364 while (1) {
365 r = mailimf_ignore_field_parse(data,
366 buf.st_size, &cur_token);
367 if (r == MAILIMF_NO_ERROR) {
368 /* do nothing */
369 }
370 else
371 break;
372 }
373
374 r = mailimf_crlf_parse(data, buf.st_size, &cur_token);
375 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
376 res = maildriver_imf_error_to_mail_error(r);
377 goto unmap;
378 }
379
380 mmapstr = mmap_string_new_len(data + cur_token, buf.st_size - cur_token);
381 if (mmapstr == NULL) {
382 res = MAIL_ERROR_MEMORY;
383
384 goto unmap;
385 }
386
387 munmap(data, buf.st_size);
388
389 r = mmap_string_ref(mmapstr);
390 if (r != 0) {
391 res = MAIL_ERROR_MEMORY;
392
393 goto err;
394 }
395
396 * result = mmapstr->str;
397 * result_len = mmapstr->len;
398
399 return MAIL_NO_ERROR;
400
401 unmap:
402 munmap(data, buf.st_size);
403 err:
404 return res;
405}
406
407
408
409static int fetch_section(mailmessage * msg_info,
410 struct mailmime * mime,
411 char ** result, size_t * result_len)
412{
413 int r;
414 FILE * f;
415 int res;
416 int col;
417 char filename[PATH_MAX];
418
419 if (msg_info->msg_mime == NULL)
420 return MAIL_ERROR_INVAL;
421
422 f = get_mime_tmp_file(msg_info, filename, sizeof(filename));
423 if (f == NULL) {
424 res = MAIL_ERROR_FILE;
425 goto err;
426 }
427
428 col = 0;
429 r = mailmime_write(f, &col, mime);
430 if (r != MAILIMF_NO_ERROR) {
431 res = maildriver_imf_error_to_mail_error(r);
432 goto close;
433 }
434
435 if (mime->mm_parent == NULL)
436 r = file_to_mmapstr(f, result, result_len);
437 else
438 r = file_body_to_mmapstr(f, result, result_len);
439
440 if (r != MAIL_NO_ERROR) {
441 res = r;
442 goto close;
443 }
444
445 fclose(f);
446 unlink(filename);
447
448 return MAIL_NO_ERROR;
449
450 close:
451 fclose(f);
452 unlink(filename);
453 err:
454 return res;
455}
456
457
458static int fetch_section_header(mailmessage * msg_info,
459 struct mailmime * mime,
460 char ** result, size_t * result_len)
461{
462 int r;
463 FILE * f;
464 int res;
465 int col;
466 char filename[PATH_MAX];
467
468 if (msg_info->msg_mime == NULL)
469 return MAIL_ERROR_INVAL;
470
471 f = get_mime_tmp_file(msg_info, filename, sizeof(filename));
472 if (f == NULL) {
473 res = MAIL_ERROR_FILE;
474 goto err;
475 }
476
477 col = 0;
478 if (mime->mm_type == MAILMIME_MESSAGE) {
479 if (mime->mm_data.mm_message.mm_fields != NULL) {
480 r = mailimf_fields_write(f, &col, mime->mm_data.mm_message.mm_fields);
481 if (r != MAILIMF_NO_ERROR) {
482 res = maildriver_imf_error_to_mail_error(r);
483 goto close;
484 }
485 mailimf_string_write(f, &col, "\r\n", 2);
486 }
487 }
488
489 r = file_to_mmapstr(f, result, result_len);
490 if (r != MAIL_NO_ERROR) {
491 res = r;
492 goto close;
493 }
494
495 fclose(f);
496 unlink(filename);
497
498 return MAIL_NO_ERROR;
499
500 close:
501 fclose(f);
502 unlink(filename);
503 err:
504 return res;
505}
506
507
508static int fetch_section_mime(mailmessage * msg_info,
509 struct mailmime * mime,
510 char ** result, size_t * result_len)
511{
512 int r;
513 FILE * f;
514 int res;
515 int col;
516 char filename[PATH_MAX];
517
518 if (msg_info->msg_mime == NULL)
519 return MAIL_ERROR_INVAL;
520
521 f = get_mime_tmp_file(msg_info, filename, sizeof(filename));
522 if (f == NULL) {
523 res = MAIL_ERROR_FILE;
524 goto err;
525 }
526
527 col = 0;
528 if (mime->mm_content_type != NULL) {
529 r = mailmime_content_write(f, &col, mime->mm_content_type);
530 if (r != MAILIMF_NO_ERROR) {
531 res = maildriver_imf_error_to_mail_error(r);
532 goto close;
533 }
534 }
535 if (mime->mm_mime_fields != NULL) {
536 r = mailmime_fields_write(f, &col, mime->mm_mime_fields);
537 if (r != MAILIMF_NO_ERROR) {
538 res = maildriver_imf_error_to_mail_error(r);
539 goto close;
540 }
541 }
542 mailimf_string_write(f, &col, "\r\n", 2);
543
544 r = file_to_mmapstr(f, result, result_len);
545 if (r != MAIL_NO_ERROR) {
546 res = r;
547 goto close;
548 }
549
550 fclose(f);
551 unlink(filename);
552
553 return MAIL_NO_ERROR;
554
555 close:
556 fclose(f);
557 unlink(filename);
558 err:
559 return res;
560}
561
562
563
564static int fetch_section_body(mailmessage * msg_info,
565 struct mailmime * mime,
566 char ** result, size_t * result_len)
567{
568 int r;
569 FILE * f;
570 int res;
571 int col;
572 char filename[PATH_MAX];
573
574 if (msg_info->msg_mime == NULL)
575 return MAIL_ERROR_INVAL;
576
577 f = get_mime_tmp_file(msg_info, filename, sizeof(filename));
578 if (f == NULL) {
579 res = MAIL_ERROR_FILE;
580 goto err;
581 }
582
583 col = 0;
584 if (mime->mm_mime_fields != NULL) {
585 r = mailmime_write(f, &col, mime);
586 if (r != MAILIMF_NO_ERROR) {
587 res = maildriver_imf_error_to_mail_error(r);
588 goto close;
589 }
590 }
591
592 if (mime->mm_type == MAILMIME_MESSAGE)
593 r = file_body_body_to_mmapstr(f, result, result_len);
594 else
595 r = file_body_to_mmapstr(f, result, result_len);
596
597 if (r != MAIL_NO_ERROR) {
598 res = r;
599 goto close;
600 }
601
602 fclose(f);
603 unlink(filename);
604
605 return MAIL_NO_ERROR;
606
607 close:
608 fclose(f);
609 unlink(filename);
610 err:
611 return res;
612}
613
614
615static int get_bodystructure(mailmessage * msg_info,
616 struct mailmime ** result)
617{
618 if (msg_info->msg_mime == NULL)
619 return MAIL_ERROR_INVAL;
620
621 * result = msg_info->msg_mime;
622
623 return MAIL_NO_ERROR;
624}
625
626
627static int fetch(mailmessage * msg_info,
628 char ** result, size_t * result_len)
629{
630 return fetch_section(msg_info, msg_info->msg_mime, result, result_len);
631}
632
633static int fetch_header(mailmessage * msg_info,
634 char ** result, size_t * result_len)
635{
636 return fetch_section_header(msg_info,
637 msg_info->msg_mime, result, result_len);
638}
639
640static int fetch_body(mailmessage * msg_info,
641 char ** result, size_t * result_len)
642{
643 return fetch_section_body(msg_info, msg_info->msg_mime, result, result_len);
644}
645
646
647static int fetch_size(mailmessage * msg_info,
648 size_t * result)
649{
650 char * msg;
651 int r;
652
653 r = fetch(msg_info, &msg, result);
654 if (r != MAIL_NO_ERROR) {
655 return r;
656 }
657
658 fetch_result_free(msg_info, msg);
659
660 return MAIL_NO_ERROR;
661}
662
663
664static mailmessage_driver local_mime_message_driver = {
665 .msg_name = "mime",
666
667 .msg_initialize = initialize,
668 .msg_uninitialize = uninitialize,
669
670 .msg_flush = flush,
671 .msg_check = check,
672
673 .msg_fetch_result_free = fetch_result_free,
674
675 .msg_fetch = fetch,
676 .msg_fetch_header = fetch_header,
677 .msg_fetch_body = fetch_body,
678 .msg_fetch_size = fetch_size,
679 .msg_get_bodystructure = get_bodystructure,
680 .msg_fetch_section = fetch_section,
681 .msg_fetch_section_header = fetch_section_header,
682 .msg_fetch_section_mime = fetch_section_mime,
683 .msg_fetch_section_body = fetch_section_body,
684 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
685
686 .msg_get_flags = NULL,
687};
688
689mailmessage_driver * mime_message_driver = &local_mime_message_driver;
diff --git a/kmicromail/libetpan/generic/mime_message_driver.h b/kmicromail/libetpan/generic/mime_message_driver.h
new file mode 100644
index 0000000..ffcdd5c
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mime_message_driver.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MIME_MESSAGE_DRIVER_H
37
38#define MIME_MESSAGE_DRIVER_H
39
40#include <libetpan/mailmessage.h>
41
42#define LIBETPAN_MIME_MESSAGE
43
44extern mailmessage_driver * mime_message_driver;
45
46mailmessage * mime_message_init(struct mailmime * mime);
47
48void mime_message_detach_mime(mailmessage * msg);
49
50int mime_message_set_tmpdir(mailmessage * msg, char * tmpdir);
51
52#endif
diff --git a/kmicromail/libetpan/generic/nntpdriver.c b/kmicromail/libetpan/generic/nntpdriver.c
new file mode 100644
index 0000000..fde5f1a
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver.c
@@ -0,0 +1,1170 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "nntpdriver.h"
37
38#include <string.h>
39#include <stdlib.h>
40
41#include "mail.h"
42#include "mailmessage.h"
43#include "nntpdriver_tools.h"
44#include "maildriver_tools.h"
45#include "nntpdriver_message.h"
46
47static int nntpdriver_initialize(mailsession * session);
48
49static void nntpdriver_uninitialize(mailsession * session);
50
51static int nntpdriver_parameters(mailsession * session,
52 int id, void * value);
53
54static int nntpdriver_connect_stream(mailsession * session, mailstream * s);
55
56static int nntpdriver_login(mailsession * session,
57 char * userid, char * password);
58
59static int nntpdriver_logout(mailsession * session);
60
61static int nntpdriver_status_folder(mailsession * session, char * mb,
62 uint32_t * result_messages,
63 uint32_t * result_recent,
64 uint32_t * result_unseen);
65
66static int nntpdriver_messages_number(mailsession * session, char * mb,
67 uint32_t * result);
68
69static int nntpdriver_append_message(mailsession * session,
70 char * message, size_t size);
71
72static int
73nntpdriver_get_envelopes_list(mailsession * session,
74 struct mailmessage_list * env_list);
75
76
77static int nntpdriver_get_messages_list(mailsession * session,
78 struct mailmessage_list ** result);
79
80static int nntpdriver_list_folders(mailsession * session, char * mb,
81 struct mail_list ** result);
82
83static int nntpdriver_lsub_folders(mailsession * session, char * mb,
84 struct mail_list ** result);
85
86static int nntpdriver_subscribe_folder(mailsession * session, char * mb);
87
88static int nntpdriver_unsubscribe_folder(mailsession * session, char * mb);
89
90static int nntpdriver_get_message(mailsession * session,
91 uint32_t num, mailmessage ** result);
92
93static int nntpdriver_get_message_by_uid(mailsession * session,
94 const char * uid,
95 mailmessage ** result);
96
97static int nntpdriver_noop(mailsession * session);
98
99static mailsession_driver local_nntp_session_driver = {
100 .sess_name = "nntp",
101
102 .sess_initialize = nntpdriver_initialize,
103 .sess_uninitialize = nntpdriver_uninitialize,
104
105 .sess_parameters = nntpdriver_parameters,
106
107 .sess_connect_stream = nntpdriver_connect_stream,
108 .sess_connect_path = NULL,
109 .sess_starttls = NULL,
110 .sess_login = nntpdriver_login,
111 .sess_logout = nntpdriver_logout,
112 .sess_noop = nntpdriver_noop,
113
114 .sess_build_folder_name = NULL,
115 .sess_create_folder = NULL,
116 .sess_delete_folder = NULL,
117 .sess_rename_folder = NULL,
118 .sess_check_folder = NULL,
119 .sess_examine_folder = NULL,
120 .sess_select_folder = nntpdriver_select_folder,
121 .sess_expunge_folder = NULL,
122 .sess_status_folder = nntpdriver_status_folder,
123 .sess_messages_number = nntpdriver_messages_number,
124 .sess_recent_number = nntpdriver_messages_number,
125 .sess_unseen_number = nntpdriver_messages_number,
126 .sess_list_folders = nntpdriver_list_folders,
127 .sess_lsub_folders = nntpdriver_lsub_folders,
128 .sess_subscribe_folder = nntpdriver_subscribe_folder,
129 .sess_unsubscribe_folder = nntpdriver_unsubscribe_folder,
130
131 .sess_append_message = nntpdriver_append_message,
132 .sess_copy_message = NULL,
133 .sess_move_message = NULL,
134
135 .sess_get_messages_list = nntpdriver_get_messages_list,
136 .sess_get_envelopes_list = nntpdriver_get_envelopes_list,
137 .sess_remove_message = NULL,
138#if 0
139 .sess_search_messages = maildriver_generic_search_messages,
140#endif
141
142 .sess_get_message = nntpdriver_get_message,
143 .sess_get_message_by_uid = nntpdriver_get_message_by_uid,
144};
145
146
147mailsession_driver * nntp_session_driver = &local_nntp_session_driver;
148
149static inline struct nntp_session_state_data *
150get_data(mailsession * session)
151{
152 return session->sess_data;
153}
154
155static inline newsnntp * get_nntp_session(mailsession * session)
156{
157 return get_data(session)->nntp_session;
158}
159
160static int nntpdriver_initialize(mailsession * session)
161{
162 struct nntp_session_state_data * data;
163 newsnntp * nntp;
164
165 nntp = newsnntp_new(0, NULL);
166 if (nntp == NULL)
167 goto err;
168
169 data = malloc(sizeof(* data));
170 if (data == NULL)
171 goto free;
172
173 data->nntp_session = nntp;
174
175 data->nntp_userid = NULL;
176 data->nntp_password = NULL;
177
178 data->nntp_group_info = NULL;
179 data->nntp_group_name = NULL;
180
181 data->nntp_subscribed_list = clist_new();
182 if (data->nntp_subscribed_list == NULL)
183 goto free_data;
184
185 data->nntp_max_articles = 0;
186
187 data->nntp_mode_reader = FALSE;
188
189 session->sess_data = data;
190
191 return MAIL_NO_ERROR;
192
193 free_data:
194 free(data);
195 free:
196 newsnntp_free(nntp);
197 err:
198 return MAIL_ERROR_MEMORY;
199}
200
201static void nntpdriver_uninitialize(mailsession * session)
202{
203 struct nntp_session_state_data * data;
204
205 data = get_data(session);
206
207 clist_foreach(data->nntp_subscribed_list, (clist_func) free, NULL);
208 clist_free(data->nntp_subscribed_list);
209
210 if (data->nntp_group_info != NULL)
211 newsnntp_group_free(data->nntp_group_info);
212
213 if (data->nntp_group_name != NULL)
214 free(data->nntp_group_name);
215
216 if (data->nntp_userid != NULL)
217 free(data->nntp_userid);
218
219 if (data->nntp_password != NULL)
220 free(data->nntp_password);
221
222 newsnntp_free(data->nntp_session);
223 free(data);
224
225 session->sess_data = NULL;
226}
227
228
229static int nntpdriver_parameters(mailsession * session,
230 int id, void * value)
231{
232 struct nntp_session_state_data * data;
233
234 data = get_data(session);
235
236 switch (id) {
237 case NNTPDRIVER_SET_MAX_ARTICLES:
238 {
239 uint32_t * param;
240
241 param = value;
242
243 data->nntp_max_articles = * param;
244 return MAIL_NO_ERROR;
245 }
246 }
247
248 return MAIL_ERROR_INVAL;
249}
250
251
252static int add_to_list(mailsession * session, char * mb)
253{
254 char * new_mb;
255 int r;
256 struct nntp_session_state_data * data;
257
258 data = get_data(session);
259
260 new_mb = strdup(mb);
261 if (new_mb == NULL)
262 return -1;
263
264 r = clist_append(data->nntp_subscribed_list, new_mb);
265 if (r < 0) {
266 free(mb);
267 return -1;
268 }
269
270 return 0;
271}
272
273static int remove_from_list(mailsession * session, char * mb)
274{
275 clistiter * cur;
276 struct nntp_session_state_data * data;
277
278 data = get_data(session);
279
280 for(cur = clist_begin(data->nntp_subscribed_list) ; cur != NULL ;
281 cur = clist_next(cur)) {
282 char * cur_name;
283
284 cur_name = clist_content(cur);
285 if (strcmp(cur_name, mb) == 0) {
286 clist_delete(data->nntp_subscribed_list, cur);
287 free(cur_name);
288 return 0;
289 }
290 }
291
292 return -1;
293}
294
295
296static int nntpdriver_connect_stream(mailsession * session, mailstream * s)
297{
298 int r;
299
300 r = newsnntp_connect(get_nntp_session(session), s);
301
302 switch (r) {
303 case NEWSNNTP_NO_ERROR:
304 return MAIL_NO_ERROR_NON_AUTHENTICATED;
305
306 default:
307 return nntpdriver_nntp_error_to_mail_error(r);
308 }
309}
310
311static int nntpdriver_login(mailsession * session,
312 char * userid, char * password)
313{
314 struct nntp_session_state_data * data;
315 char * new_userid;
316 char * new_password;
317
318 data = get_data(session);
319
320 if (userid != NULL) {
321 new_userid = strdup(userid);
322 if (new_userid == NULL)
323 goto err;
324 }
325 else
326 new_userid = NULL;
327
328 if (password != NULL) {
329 new_password = strdup(password);
330 if (new_password == NULL)
331 goto free_uid;
332 }
333 else
334 new_password = NULL;
335
336 data->nntp_userid = new_userid;
337 data->nntp_password = new_password;
338
339 return MAIL_NO_ERROR;
340
341 free_uid:
342 if (new_userid != NULL)
343 free(new_userid);
344 err:
345 return MAIL_ERROR_MEMORY;
346}
347
348static int nntpdriver_logout(mailsession * session)
349{
350 int r;
351
352 r = newsnntp_quit(get_nntp_session(session));
353
354 return nntpdriver_nntp_error_to_mail_error(r);
355}
356
357
358static int nntpdriver_status_folder(mailsession * session, char * mb,
359 uint32_t * result_messages,
360 uint32_t * result_recent,
361 uint32_t * result_unseen)
362{
363 uint32_t count;
364 int r;
365
366 r = nntpdriver_select_folder(session, mb);
367 if (r != MAIL_NO_ERROR)
368 return r;
369
370 r = nntpdriver_messages_number(session, mb, &count);
371 if (r != MAIL_NO_ERROR)
372 return r;
373
374 * result_messages = count;
375 * result_recent = count;
376 * result_unseen = count;
377
378 return MAIL_NO_ERROR;
379}
380
381static int nntpdriver_messages_number(mailsession * session, char * mb,
382 uint32_t * result)
383{
384 int r;
385 struct nntp_session_state_data * data;
386
387 if (mb != NULL) {
388 r = nntpdriver_select_folder(session, mb);
389 if (r != MAIL_NO_ERROR)
390 return r;
391 }
392
393 data = get_data(session);
394
395 if (data->nntp_group_info == NULL)
396 return MAIL_ERROR_FOLDER_NOT_FOUND;
397
398 * result = data->nntp_group_info->grp_last -
399 data->nntp_group_info->grp_first + 1;
400
401 return MAIL_NO_ERROR;
402}
403
404static int nntpdriver_list_folders(mailsession * session, char * mb,
405 struct mail_list ** result)
406{
407 int r;
408 clist * group_list;
409 newsnntp * nntp;
410 clistiter * cur;
411 char * new_mb;
412 int done;
413 clist * list;
414 struct mail_list * ml;
415 int res;
416
417 nntp = get_nntp_session(session);
418
419 new_mb = NULL;
420 if ((mb != NULL) && (*mb != '\0')) {
421 new_mb = malloc(strlen(mb) + 3);
422 if (new_mb == NULL) {
423 res = MAIL_ERROR_MEMORY;
424 goto err;
425 }
426 strcpy(new_mb, mb);
427 strcat(new_mb, ".*");
428 }
429
430 done = FALSE;
431 do {
432 if (new_mb != NULL)
433 r = newsnntp_list_active(nntp, new_mb, &group_list);
434 else
435 r = newsnntp_list(nntp, &group_list);
436
437 switch (r) {
438 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
439 r = nntpdriver_authenticate_user(session);
440 if (r != MAIL_NO_ERROR) {
441 res = r;
442 goto err;
443 }
444 break;
445
446 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
447 r = nntpdriver_authenticate_password(session);
448 if (r != MAIL_NO_ERROR) {
449 res = r;
450 goto err;
451 }
452 break;
453
454 case NEWSNNTP_NO_ERROR:
455 if (new_mb != NULL)
456 free(new_mb);
457 done = TRUE;
458 break;
459
460 default:
461 if (new_mb != NULL)
462 free(new_mb);
463 return nntpdriver_nntp_error_to_mail_error(r);
464 }
465 }
466 while (!done);
467
468 list = clist_new();
469 if (list == NULL) {
470 res = MAIL_ERROR_MEMORY;
471 goto err;
472 }
473
474 for(cur = clist_begin(group_list) ; cur != NULL ;
475 cur = clist_next(cur)) {
476 struct newsnntp_group_info * info;
477 char * new_name;
478
479 info = clist_content(cur);
480 new_name = strdup(info->grp_name);
481 if (new_name == NULL) {
482 res = MAIL_ERROR_MEMORY;
483 goto free_list;
484 }
485
486 r = clist_append(list, new_name);
487 if (r < 0) {
488 free(new_name);
489 res = MAIL_ERROR_MEMORY;
490 goto free_list;
491 }
492 }
493
494 ml = mail_list_new(list);
495 if (ml == NULL) {
496 res = MAIL_ERROR_MEMORY;
497 goto free_list;
498 }
499
500 newsnntp_list_free(group_list);
501
502 * result = ml;
503
504 return MAIL_NO_ERROR;
505
506 free_list:
507 clist_foreach(list, (clist_func) free, NULL);
508 clist_free(list);
509 newsnntp_list_free(group_list);
510 err:
511 return res;
512}
513
514static int nntpdriver_lsub_folders(mailsession * session, char * mb,
515 struct mail_list ** result)
516{
517 clist * subscribed;
518 clist * lsub_result;
519 clistiter * cur;
520 struct mail_list * lsub;
521 size_t length;
522 int res;
523 int r;
524 struct nntp_session_state_data * data;
525
526 length = strlen(mb);
527
528 data = get_data(session);
529
530 subscribed = data->nntp_subscribed_list;
531 lsub_result = clist_new();
532 if (lsub_result == NULL) {
533 res = MAIL_ERROR_MEMORY;
534 goto err;
535 }
536
537 for(cur = clist_begin(subscribed) ; cur != NULL ;
538 cur = clist_next(cur)) {
539 char * cur_mb;
540 char * new_mb;
541
542 cur_mb = clist_content(cur);
543
544 if (strncmp(mb, cur_mb, length) == 0) {
545 new_mb = strdup(cur_mb);
546 if (new_mb == NULL) {
547 res = MAIL_ERROR_MEMORY;
548 goto free_list;
549 }
550
551 r = clist_append(lsub_result, new_mb);
552 if (r < 0) {
553 free(new_mb);
554 res = MAIL_ERROR_MEMORY;
555 goto free_list;
556 }
557 }
558 }
559
560 lsub = mail_list_new(lsub_result);
561 if (lsub == NULL) {
562 res = MAIL_ERROR_MEMORY;
563 goto free_list;
564 }
565
566 * result = lsub;
567
568 return MAIL_NO_ERROR;
569
570 free_list:
571 clist_foreach(lsub_result, (clist_func) free, NULL);
572 clist_free(lsub_result);
573 err:
574 return res;
575}
576
577static int nntpdriver_subscribe_folder(mailsession * session, char * mb)
578{
579 int r;
580
581 r = add_to_list(session, mb);
582 if (r < 0)
583 return MAIL_ERROR_SUBSCRIBE;
584
585 return MAIL_NO_ERROR;
586}
587
588static int nntpdriver_unsubscribe_folder(mailsession * session, char * mb)
589{
590 int r;
591
592 r = remove_from_list(session, mb);
593 if (r < 0)
594 return MAIL_ERROR_UNSUBSCRIBE;
595
596 return MAIL_NO_ERROR;
597}
598
599
600
601/* messages operations */
602
603static int nntpdriver_append_message(mailsession * session,
604 char * message, size_t size)
605{
606 int r;
607 struct nntp_session_state_data * data;
608
609 data = get_data(session);
610
611 do {
612 r = newsnntp_post(get_nntp_session(session), message, size);
613 switch (r) {
614 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
615 r = nntpdriver_authenticate_user(session);
616 if (r != MAIL_NO_ERROR)
617 return r;
618 break;
619
620 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
621 r = nntpdriver_authenticate_password(session);
622 if (r != MAIL_NO_ERROR)
623 return r;
624 break;
625
626 default:
627 return nntpdriver_nntp_error_to_mail_error(r);
628 }
629 }
630 while (1);
631}
632
633
634static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item,
635 struct mailimf_fields ** result);
636
637
638static int
639nntpdriver_get_envelopes_list(mailsession * session,
640 struct mailmessage_list * env_list)
641{
642 newsnntp * nntp;
643 int r;
644 struct nntp_session_state_data * data;
645 clist * list;
646 int done;
647 clistiter * cur;
648 uint32_t first_seq;
649 unsigned int i;
650
651 nntp = get_nntp_session(session);
652
653 data = get_data(session);
654
655 if (data->nntp_group_info == NULL)
656 return MAIL_ERROR_BAD_STATE;
657
658 first_seq = data->nntp_group_info->grp_first;
659
660 if (carray_count(env_list->msg_tab) > 0) {
661 mailmessage * msg;
662
663 msg = carray_get(env_list->msg_tab, 0);
664
665 first_seq = msg->msg_index;
666 }
667
668 if (carray_count(env_list->msg_tab) > 0) {
669 i = carray_count(env_list->msg_tab) - 1;
670 while (1) {
671 mailmessage * msg;
672
673 msg = carray_get(env_list->msg_tab, i);
674
675 if (msg->msg_fields != NULL) {
676 first_seq = msg->msg_index + 1;
677 break;
678 }
679
680 if (i == 0)
681 break;
682
683 i --;
684 }
685 }
686
687 if (first_seq > data->nntp_group_info->grp_last) {
688 list = NULL;
689 }
690 else {
691 done = FALSE;
692 do {
693 r = newsnntp_xover_range(nntp, first_seq,
694 data->nntp_group_info->grp_last, &list);
695
696 switch (r) {
697 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
698 r = nntpdriver_authenticate_user(session);
699 if (r != MAIL_NO_ERROR)
700 return r;
701 break;
702
703 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
704 r = nntpdriver_authenticate_password(session);
705 if (r != MAIL_NO_ERROR)
706 return r;
707 break;
708
709 case NEWSNNTP_NO_ERROR:
710 done = TRUE;
711 break;
712
713 default:
714 return nntpdriver_nntp_error_to_mail_error(r);
715 }
716 }
717 while (!done);
718 }
719
720#if 0
721 i = 0;
722 j = 0;
723
724 if (list != NULL) {
725 for(cur = clist_begin(list) ; cur != NULL ; cur = clist_next(cur)) {
726 struct newsnntp_xover_resp_item * item;
727 struct mailimf_fields * fields;
728
729 item = clist_content(cur);
730
731 while (i < carray_count(env_list->msg_tab)) {
732 mailmessage * info;
733
734 info = carray_get(env_list->msg_tab, i);
735
736 if (item->ovr_article == info->msg_index) {
737
738 if (info->fields == NULL) {
739 r = xover_resp_to_fields(item, &fields);
740 if (r == MAIL_NO_ERROR) {
741 info->fields = fields;
742 }
743
744 info->size = item->ovr_size;
745
746 carray_set(env_list->msg_tab, j, info);
747 j ++;
748 i ++;
749 break;
750 }
751 else {
752 carray_set(env_list->msg_tab, j, info);
753 j ++;
754 }
755 }
756 else {
757 if (info->fields != NULL) {
758 carray_set(env_list->msg_tab, j, info);
759 j ++;
760 }
761 else {
762 if (info->flags != NULL) {
763 info->flags->flags &= ~MAIL_FLAG_NEW;
764 info->flags->flags |= MAIL_FLAG_SEEN | MAIL_FLAG_DELETED;
765 mailmessage_check(info);
766 }
767 mailmessage_free(info);
768 carray_set(env_list->msg_tab, i, NULL);
769 }
770 }
771
772 i ++;
773 }
774 }
775 }
776
777 while (i < carray_count(env_list->msg_tab)) {
778 mailmessage * info;
779
780 info = carray_get(env_list->msg_tab, i);
781 if (info->fields != NULL) {
782 carray_set(env_list->msg_tab, j, info);
783 j ++;
784 }
785 else {
786 if (info->flags != NULL) {
787 info->flags->flags &= ~MAIL_FLAG_NEW;
788 info->flags->flags |= MAIL_FLAG_SEEN | MAIL_FLAG_DELETED;
789 mailmessage_check(info);
790 }
791 mailmessage_free(info);
792 carray_set(env_list->msg_tab, i, NULL);
793 }
794
795 i ++;
796 }
797
798 r = carray_set_size(env_list->msg_tab, j);
799 if (r < 0) {
800 if (list != NULL)
801 newsnntp_xover_resp_list_free(list);
802 return MAIL_ERROR_MEMORY;
803 }
804#endif
805 i = 0;
806
807 if (list != NULL) {
808 for(cur = clist_begin(list) ; cur != NULL ; cur = clist_next(cur)) {
809 struct newsnntp_xover_resp_item * item;
810 struct mailimf_fields * fields;
811
812 item = clist_content(cur);
813
814 while (i < carray_count(env_list->msg_tab)) {
815 mailmessage * info;
816
817 info = carray_get(env_list->msg_tab, i);
818
819 if (item->ovr_article == info->msg_index) {
820
821 if (info->msg_fields == NULL) {
822 r = xover_resp_to_fields(item, &fields);
823 if (r == MAIL_NO_ERROR) {
824 info->msg_fields = fields;
825 }
826
827 info->msg_size = item->ovr_size;
828
829 i ++;
830 break;
831 }
832 }
833#if 0
834 else if ((info->fields == NULL) && (info->flags != NULL)) {
835 info->flags->flags &= ~MAIL_FLAG_NEW;
836 info->flags->flags |= MAIL_FLAG_CANCELLED;
837 mailmessage_check(info);
838 }
839#endif
840
841 i ++;
842 }
843 }
844 }
845
846#if 0
847 while (i < env_list->msg_tab->len) {
848 mailmessage * info;
849
850 info = carray_get(env_list->msg_tab, i);
851 if ((info->fields == NULL) && (info->flags != NULL)) {
852 info->flags->flags &= ~MAIL_FLAG_NEW;
853 info->flags->flags |= MAIL_FLAG_CANCELLED;
854 mailmessage_check(info);
855 }
856
857 i ++;
858 }
859#endif
860
861 if (list != NULL)
862 newsnntp_xover_resp_list_free(list);
863
864 return MAIL_NO_ERROR;
865}
866
867
868static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item,
869 struct mailimf_fields ** result)
870{
871 size_t cur_token;
872 clist * list;
873 int r;
874 struct mailimf_fields * fields;
875 int res;
876
877 list = clist_new();
878 if (list == NULL) {
879 res = MAIL_ERROR_MEMORY;
880 goto err;
881 }
882
883 if (item->ovr_subject != NULL) {
884 char * subject_str;
885 struct mailimf_subject * subject;
886 struct mailimf_field * field;
887
888 subject_str = strdup(item->ovr_subject);
889 if (subject_str == NULL) {
890 res = MAIL_ERROR_MEMORY;
891 goto free_list;
892 }
893
894 subject = mailimf_subject_new(subject_str);
895 if (subject == NULL) {
896 free(subject_str);
897 res = MAIL_ERROR_MEMORY;
898 goto free_list;
899 }
900
901 field = mailimf_field_new(MAILIMF_FIELD_SUBJECT,
902 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
903 NULL, NULL, NULL,
904 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
905 NULL, subject, NULL, NULL, NULL);
906 if (field == NULL) {
907 mailimf_subject_free(subject);
908 res = MAIL_ERROR_MEMORY;
909 goto free_list;
910 }
911
912 r = clist_append(list, field);
913 if (r < 0) {
914 mailimf_field_free(field);
915 res = MAIL_ERROR_MEMORY;
916 goto free_list;
917 }
918 }
919
920 if (item->ovr_author != NULL) {
921 struct mailimf_mailbox_list * mb_list;
922 struct mailimf_from * from;
923 struct mailimf_field * field;
924
925 cur_token = 0;
926 r = mailimf_mailbox_list_parse(item->ovr_author, strlen(item->ovr_author),
927 &cur_token, &mb_list);
928 switch (r) {
929 case MAILIMF_NO_ERROR:
930 from = mailimf_from_new(mb_list);
931 if (from == NULL) {
932 mailimf_mailbox_list_free(mb_list);
933 res = MAIL_ERROR_MEMORY;
934 goto free_list;
935 }
936
937 field = mailimf_field_new(MAILIMF_FIELD_FROM,
938 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
939 NULL, NULL, from,
940 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
941 NULL, NULL, NULL, NULL, NULL);
942 if (field == NULL) {
943 mailimf_from_free(from);
944 res = MAIL_ERROR_MEMORY;
945 goto free_list;
946 }
947
948 r = clist_append(list, field);
949 if (r < 0) {
950 mailimf_field_free(field);
951 res = MAIL_ERROR_MEMORY;
952 goto free_list;
953 }
954 break;
955
956 case MAILIMF_ERROR_PARSE:
957 break;
958
959 default:
960 res = maildriver_imf_error_to_mail_error(r);
961 goto free_list;
962 }
963 }
964
965 if (item->ovr_date != NULL) {
966 struct mailimf_date_time * date_time;
967 struct mailimf_orig_date * orig_date;
968 struct mailimf_field * field;
969
970 cur_token = 0;
971 r = mailimf_date_time_parse(item->ovr_date, strlen(item->ovr_date),
972 &cur_token, &date_time);
973 switch (r) {
974 case MAILIMF_NO_ERROR:
975 orig_date = mailimf_orig_date_new(date_time);
976 if (orig_date == NULL) {
977 mailimf_date_time_free(date_time);
978 res = MAIL_ERROR_MEMORY;
979 goto free_list;
980 }
981
982 field = mailimf_field_new(MAILIMF_FIELD_ORIG_DATE,
983 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
984 NULL, orig_date, NULL,
985 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
986 NULL, NULL, NULL, NULL, NULL);
987 if (field == NULL) {
988 mailimf_orig_date_free(orig_date);
989 res = MAIL_ERROR_MEMORY;
990 goto free_list;
991 }
992
993 r = clist_append(list, field);
994 if (r < 0) {
995 mailimf_field_free(field);
996 res = MAIL_ERROR_MEMORY;
997 goto free_list;
998 }
999 break;
1000
1001 case MAILIMF_ERROR_PARSE:
1002 break;
1003
1004 default:
1005 res = maildriver_imf_error_to_mail_error(r);
1006 goto free_list;
1007 }
1008 }
1009
1010 if (item->ovr_message_id != NULL) {
1011 char * msgid_str;
1012 struct mailimf_message_id * msgid;
1013 struct mailimf_field * field;
1014
1015 cur_token = 0;
1016 r = mailimf_msg_id_parse(item->ovr_message_id, strlen(item->ovr_message_id),
1017 &cur_token, &msgid_str);
1018
1019 switch (r) {
1020 case MAILIMF_NO_ERROR:
1021 msgid = mailimf_message_id_new(msgid_str);
1022 if (msgid == NULL) {
1023 mailimf_msg_id_free(msgid_str);
1024 res = MAIL_ERROR_MEMORY;
1025 goto free_list;
1026 }
1027
1028 field = mailimf_field_new(MAILIMF_FIELD_MESSAGE_ID,
1029 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1030 NULL, NULL, NULL,
1031 NULL, NULL, NULL, NULL, NULL, msgid, NULL,
1032 NULL, NULL, NULL, NULL, NULL);
1033
1034 r = clist_append(list, field);
1035 if (r < 0) {
1036 mailimf_field_free(field);
1037 res = MAIL_ERROR_MEMORY;
1038 goto free_list;
1039 }
1040 break;
1041
1042 case MAILIMF_ERROR_PARSE:
1043 break;
1044
1045 default:
1046 res = maildriver_imf_error_to_mail_error(r);
1047 goto free_list;
1048 }
1049 }
1050
1051 if (item->ovr_references != NULL) {
1052 clist * msgid_list;
1053 struct mailimf_references * references;
1054 struct mailimf_field * field;
1055
1056 cur_token = 0;
1057
1058 r = mailimf_msg_id_list_parse(item->ovr_references, strlen(item->ovr_references),
1059 &cur_token, &msgid_list);
1060
1061 switch (r) {
1062 case MAILIMF_NO_ERROR:
1063 references = mailimf_references_new(msgid_list);
1064 if (references == NULL) {
1065 clist_foreach(msgid_list,
1066 (clist_func) mailimf_msg_id_free, NULL);
1067 clist_free(msgid_list);
1068 res = MAIL_ERROR_MEMORY;
1069 goto free_list;
1070 }
1071
1072 field = mailimf_field_new(MAILIMF_FIELD_REFERENCES,
1073 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1074 NULL, NULL, NULL,
1075 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1076 references, NULL, NULL, NULL, NULL);
1077
1078 r = clist_append(list, field);
1079 if (r < 0) {
1080 mailimf_field_free(field);
1081 res = MAIL_ERROR_MEMORY;
1082 goto free_list;
1083 }
1084
1085 case MAILIMF_ERROR_PARSE:
1086 break;
1087
1088 default:
1089 res = maildriver_imf_error_to_mail_error(r);
1090 goto free_list;
1091 }
1092 }
1093
1094 fields = mailimf_fields_new(list);
1095 if (fields == NULL) {
1096 res = MAIL_ERROR_MEMORY;
1097 goto free_list;
1098 }
1099
1100 * result = fields;
1101
1102 return MAIL_NO_ERROR;
1103
1104 free_list:
1105 clist_foreach(list, (clist_func) mailimf_field_free, NULL);
1106 clist_free(list);
1107 err:
1108 return res;
1109}
1110
1111
1112/* get messages list with group info */
1113
1114static int nntpdriver_get_messages_list(mailsession * session,
1115 struct mailmessage_list ** result)
1116{
1117 return nntp_get_messages_list(session, session, nntp_message_driver, result);
1118
1119}
1120
1121static int nntpdriver_get_message(mailsession * session,
1122 uint32_t num, mailmessage ** result)
1123{
1124 mailmessage * msg_info;
1125 int r;
1126
1127 msg_info = mailmessage_new();
1128 if (msg_info == NULL)
1129 return MAIL_ERROR_MEMORY;
1130
1131 r = mailmessage_init(msg_info, session, nntp_message_driver, num, 0);
1132 if (r != MAIL_NO_ERROR) {
1133 mailmessage_free(msg_info);
1134 return r;
1135 }
1136
1137 * result = msg_info;
1138
1139 return MAIL_NO_ERROR;
1140}
1141
1142static int nntpdriver_noop(mailsession * session)
1143{
1144 newsnntp * nntp;
1145 int r;
1146 struct tm tm;
1147
1148 nntp = get_nntp_session(session);
1149
1150 r = newsnntp_date(nntp, &tm);
1151
1152 return nntpdriver_nntp_error_to_mail_error(r);
1153}
1154
1155static int nntpdriver_get_message_by_uid(mailsession * session,
1156 const char * uid,
1157 mailmessage ** result)
1158{
1159 uint32_t num;
1160 char * p;
1161
1162 if (uid == NULL)
1163 return MAIL_ERROR_INVAL;
1164
1165 num = strtoul(uid, &p, 10);
1166 if ((p == uid) || (* p != '\0'))
1167 return MAIL_ERROR_INVAL;
1168
1169 return nntpdriver_get_message(session, num, result);
1170 }
diff --git a/kmicromail/libetpan/generic/nntpdriver.h b/kmicromail/libetpan/generic/nntpdriver.h
new file mode 100644
index 0000000..45bfeab
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NNTPDRIVER_H
37
38#define NNTPDRIVER_H
39
40#include <libetpan/nntpdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * nntp_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/nntpdriver_cached.c b/kmicromail/libetpan/generic/nntpdriver_cached.c
new file mode 100644
index 0000000..1f8a8af
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_cached.c
@@ -0,0 +1,1048 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "nntpdriver_cached.h"
37
38#include "libetpan-config.h"
39
40#include <string.h>
41#include <stdio.h>
42#include <sys/types.h>
43#include <sys/stat.h>
44#include <fcntl.h>
45#include <unistd.h>
46#include <stdlib.h>
47
48#include "mail_cache_db.h"
49
50#include "mail.h"
51#include "mailmessage.h"
52#include "maildriver_tools.h"
53#include "nntpdriver.h"
54#include "maildriver.h"
55#include "newsnntp.h"
56#include "generic_cache.h"
57#include "imfcache.h"
58#include "maillock.h"
59#include "nntpdriver_cached_message.h"
60#include "nntpdriver_tools.h"
61
62static int nntpdriver_cached_initialize(mailsession * session);
63
64static void nntpdriver_cached_uninitialize(mailsession * session);
65
66static int nntpdriver_cached_parameters(mailsession * session,
67 int id, void * value);
68
69static int nntpdriver_cached_connect_stream(mailsession * session,
70 mailstream * s);
71
72static int nntpdriver_cached_login(mailsession * session,
73 char * userid, char * password);
74
75static int nntpdriver_cached_logout(mailsession * session);
76
77static int nntpdriver_cached_check_folder(mailsession * session);
78
79static int nntpdriver_cached_select_folder(mailsession * session, char * mb);
80
81static int nntpdriver_cached_status_folder(mailsession * session,
82 char * mb,
83 uint32_t * result_messages,
84 uint32_t * result_recent,
85 uint32_t * result_unseen);
86
87static int nntpdriver_cached_messages_number(mailsession * session, char * mb,
88 uint32_t * result);
89
90static int nntpdriver_cached_recent_number(mailsession * session, char * mb,
91 uint32_t * result);
92
93static int nntpdriver_cached_unseen_number(mailsession * session, char * mb,
94 uint32_t * result);
95
96static int nntpdriver_cached_append_message(mailsession * session,
97 char * message, size_t size);
98
99static int
100nntpdriver_cached_get_envelopes_list(mailsession * session,
101 struct mailmessage_list * env_list);
102
103
104static int
105nntpdriver_cached_get_messages_list(mailsession * session,
106 struct mailmessage_list ** result);
107
108static int nntpdriver_cached_list_folders(mailsession * session, char * mb,
109 struct mail_list ** result);
110
111static int nntpdriver_cached_lsub_folders(mailsession * session, char * mb,
112 struct mail_list ** result);
113
114static int nntpdriver_cached_subscribe_folder(mailsession * session,
115 char * mb);
116
117static int nntpdriver_cached_unsubscribe_folder(mailsession * session,
118 char * mb);
119
120static int nntpdriver_cached_get_message(mailsession * session,
121 uint32_t num, mailmessage ** result);
122
123static int nntpdriver_cached_noop(mailsession * session);
124
125static int nntpdriver_cached_get_message_by_uid(mailsession * session,
126 const char * uid,
127 mailmessage ** result);
128
129static mailsession_driver local_nntp_cached_session_driver = {
130 .sess_name = "nntp-cached",
131
132 .sess_initialize = nntpdriver_cached_initialize,
133 .sess_uninitialize = nntpdriver_cached_uninitialize,
134
135 .sess_parameters = nntpdriver_cached_parameters,
136
137 .sess_connect_stream = nntpdriver_cached_connect_stream,
138 .sess_connect_path = NULL,
139 .sess_starttls = NULL,
140 .sess_login = nntpdriver_cached_login,
141 .sess_logout = nntpdriver_cached_logout,
142 .sess_noop = nntpdriver_cached_noop,
143
144 .sess_build_folder_name = NULL,
145 .sess_create_folder = NULL,
146 .sess_delete_folder = NULL,
147 .sess_rename_folder = NULL,
148 .sess_check_folder = nntpdriver_cached_check_folder,
149 .sess_examine_folder = NULL,
150 .sess_select_folder = nntpdriver_cached_select_folder,
151 .sess_expunge_folder = NULL,
152 .sess_status_folder = nntpdriver_cached_status_folder,
153 .sess_messages_number = nntpdriver_cached_messages_number,
154 .sess_recent_number = nntpdriver_cached_recent_number,
155 .sess_unseen_number = nntpdriver_cached_unseen_number,
156 .sess_list_folders = nntpdriver_cached_list_folders,
157 .sess_lsub_folders = nntpdriver_cached_lsub_folders,
158 .sess_subscribe_folder = nntpdriver_cached_subscribe_folder,
159 .sess_unsubscribe_folder = nntpdriver_cached_unsubscribe_folder,
160
161 .sess_append_message = nntpdriver_cached_append_message,
162 .sess_copy_message = NULL,
163 .sess_move_message = NULL,
164
165 .sess_get_messages_list = nntpdriver_cached_get_messages_list,
166 .sess_get_envelopes_list = nntpdriver_cached_get_envelopes_list,
167 .sess_remove_message = NULL,
168#if 0
169 .sess_search_messages = maildriver_generic_search_messages,
170#endif
171
172 .sess_get_message = nntpdriver_cached_get_message,
173 .sess_get_message_by_uid = nntpdriver_cached_get_message_by_uid,
174};
175
176
177mailsession_driver * nntp_cached_session_driver =
178&local_nntp_cached_session_driver;
179
180#define ENV_NAME "env.db"
181#define FLAGS_NAME "flags.db"
182
183
184
185static void read_article_seq(mailsession * session,
186 uint32_t * pfirst, uint32_t * plast);
187
188static void write_article_seq(mailsession * session,
189 uint32_t first, uint32_t last);
190
191
192static inline struct nntp_cached_session_state_data *
193get_cached_data(mailsession * session)
194{
195 return session->sess_data;
196}
197
198static inline mailsession * get_ancestor(mailsession * session)
199{
200 return get_cached_data(session)->nntp_ancestor;
201}
202
203static inline struct nntp_session_state_data *
204get_ancestor_data(mailsession * session)
205{
206 return get_ancestor(session)->sess_data;
207}
208
209static inline newsnntp * get_nntp_session(mailsession * session)
210{
211 return get_ancestor_data(session)->nntp_session;
212}
213
214static int nntpdriver_cached_initialize(mailsession * session)
215{
216 struct nntp_cached_session_state_data * data;
217
218 data = malloc(sizeof(* data));
219 if (data == NULL)
220 goto err;
221
222 data->nntp_flags_store = mail_flags_store_new();
223 if (data->nntp_flags_store == NULL)
224 goto free;
225
226 data->nntp_ancestor = mailsession_new(nntp_session_driver);
227 if (data->nntp_ancestor == NULL)
228 goto free_store;
229
230 session->sess_data = data;
231
232 return MAIL_NO_ERROR;
233
234 free_store:
235 mail_flags_store_free(data->nntp_flags_store);
236 free:
237 free(data);
238 err:
239 return MAIL_ERROR_MEMORY;
240}
241
242static int nntp_flags_store_process(char * flags_directory, char * group_name,
243 struct mail_flags_store * flags_store)
244{
245 char filename_flags[PATH_MAX];
246 struct mail_cache_db * cache_db_flags;
247 MMAPString * mmapstr;
248 unsigned int i;
249 int r;
250 int res;
251
252 if (carray_count(flags_store->fls_tab) == 0)
253 return MAIL_NO_ERROR;
254
255 if (group_name == NULL)
256 return MAIL_NO_ERROR;
257
258 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
259 flags_directory, group_name, FLAGS_NAME);
260
261 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
262 if (r < 0) {
263 res = MAIL_ERROR_FILE;
264 goto err;
265 }
266
267 mmapstr = mmap_string_new("");
268 if (mmapstr == NULL) {
269 res = MAIL_ERROR_MEMORY;
270 goto close_db_flags;
271 }
272
273 for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
274 mailmessage * msg;
275
276 msg = carray_get(flags_store->fls_tab, i);
277
278 r = nntpdriver_write_cached_flags(cache_db_flags, mmapstr,
279 msg->msg_index, msg->msg_flags);
280 }
281
282 mmap_string_free(mmapstr);
283 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
284
285 mail_flags_store_clear(flags_store);
286
287 return MAIL_NO_ERROR;
288
289 close_db_flags:
290 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
291 err:
292 return res;
293}
294
295static void nntpdriver_cached_uninitialize(mailsession * session)
296{
297 struct nntp_cached_session_state_data * cached_data;
298 struct nntp_session_state_data * ancestor_data;
299
300 cached_data = get_cached_data(session);
301 ancestor_data = get_ancestor_data(session);
302
303 nntp_flags_store_process(cached_data->nntp_flags_directory,
304 ancestor_data->nntp_group_name,
305 cached_data->nntp_flags_store);
306
307 mail_flags_store_free(cached_data->nntp_flags_store);
308
309 mailsession_free(cached_data->nntp_ancestor);
310 free(cached_data);
311
312 session->sess_data = NULL;
313}
314
315static int nntpdriver_cached_parameters(mailsession * session,
316 int id, void * value)
317{
318 struct nntp_cached_session_state_data * cached_data;
319 int r;
320
321 cached_data = get_cached_data(session);
322
323 switch (id) {
324 case NNTPDRIVER_CACHED_SET_CACHE_DIRECTORY:
325 strncpy(cached_data->nntp_cache_directory, value, PATH_MAX);
326 cached_data->nntp_cache_directory[PATH_MAX - 1] = '\0';
327
328 r = generic_cache_create_dir(cached_data->nntp_cache_directory);
329 if (r != MAIL_NO_ERROR)
330 return r;
331
332 return MAIL_NO_ERROR;
333
334 case NNTPDRIVER_CACHED_SET_FLAGS_DIRECTORY:
335 strncpy(cached_data->nntp_flags_directory, value, PATH_MAX);
336 cached_data->nntp_flags_directory[PATH_MAX - 1] = '\0';
337
338 r = generic_cache_create_dir(cached_data->nntp_flags_directory);
339 if (r != MAIL_NO_ERROR)
340 return r;
341
342 return MAIL_NO_ERROR;
343
344 default:
345 return mailsession_parameters(get_ancestor(session), id, value);
346 }
347}
348
349static int nntpdriver_cached_connect_stream(mailsession * session,
350 mailstream * s)
351{
352 return mailsession_connect_stream(get_ancestor(session), s);
353}
354
355static int nntpdriver_cached_login(mailsession * session,
356 char * userid, char * password)
357{
358 return mailsession_login(get_ancestor(session), userid, password);
359}
360
361static int nntpdriver_cached_logout(mailsession * session)
362{
363 struct nntp_cached_session_state_data * cached_data;
364 struct nntp_session_state_data * ancestor_data;
365
366 cached_data = get_cached_data(session);
367 ancestor_data = get_ancestor_data(session);
368
369 nntp_flags_store_process(cached_data->nntp_flags_directory,
370 ancestor_data->nntp_group_name,
371 cached_data->nntp_flags_store);
372
373 return mailsession_logout(get_ancestor(session));
374}
375
376static int nntpdriver_cached_select_folder(mailsession * session, char * mb)
377{
378 int r;
379 struct nntp_session_state_data * ancestor_data;
380 struct nntp_cached_session_state_data * cached_data;
381 int res;
382 char key[PATH_MAX];
383
384 cached_data = get_cached_data(session);
385 ancestor_data = get_ancestor_data(session);
386
387 nntp_flags_store_process(cached_data->nntp_flags_directory,
388 ancestor_data->nntp_group_name,
389 cached_data->nntp_flags_store);
390
391 r = mailsession_select_folder(get_ancestor(session), mb);
392 if (r != MAIL_NO_ERROR)
393 return r;
394
395 if (ancestor_data->nntp_group_name == NULL)
396 return MAIL_ERROR_BAD_STATE;
397
398 snprintf(key, PATH_MAX, "%s/%s", cached_data->nntp_cache_directory,
399 ancestor_data->nntp_group_name);
400
401 r = generic_cache_create_dir(key);
402 if (r != MAIL_NO_ERROR) {
403 res = r;
404 goto err;
405 }
406
407 snprintf(key, PATH_MAX, "%s/%s", cached_data->nntp_flags_directory,
408 ancestor_data->nntp_group_name);
409
410 r = generic_cache_create_dir(key);
411 if (r != MAIL_NO_ERROR) {
412 res = r;
413 goto err;
414 }
415
416 return MAIL_NO_ERROR;
417
418 err:
419 return res;
420}
421
422static int nntpdriver_cached_check_folder(mailsession * session)
423{
424 struct nntp_session_state_data * ancestor_data;
425 struct nntp_cached_session_state_data * cached_data;
426
427 cached_data = get_cached_data(session);
428 ancestor_data = get_ancestor_data(session);
429
430 nntp_flags_store_process(cached_data->nntp_flags_directory,
431 ancestor_data->nntp_group_name,
432 cached_data->nntp_flags_store);
433
434 return MAIL_NO_ERROR;
435}
436
437
438static int nntpdriver_cached_status_folder(mailsession * session,
439 char * mb, uint32_t * result_messages, uint32_t * result_recent,
440 uint32_t * result_unseen)
441{
442 int res;
443 struct nntp_cached_session_state_data * cached_data;
444 struct nntp_session_state_data * ancestor_data;
445 char filename_flags[PATH_MAX];
446 struct mail_cache_db * cache_db_flags;
447 MMAPString * mmapstr;
448 uint32_t i;
449 int r;
450 uint32_t recent;
451 uint32_t unseen;
452 uint32_t first;
453 uint32_t last;
454 uint32_t count;
455 uint32_t additionnal;
456
457 r = nntpdriver_cached_select_folder(session, mb);
458 if (r != MAIL_NO_ERROR) {
459 res = r;
460 goto err;
461 }
462
463 read_article_seq(session, &first, &last);
464
465 count = 0;
466 recent = 0;
467 unseen = 0;
468
469 ancestor_data = get_ancestor_data(session);
470 cached_data = get_cached_data(session);
471 if (ancestor_data->nntp_group_name == NULL) {
472 res = MAIL_ERROR_BAD_STATE;
473 goto err;
474 }
475
476 if (ancestor_data->nntp_group_info->grp_first > first)
477 first = ancestor_data->nntp_group_info->grp_first;
478 if (last < first)
479 last = ancestor_data->nntp_group_info->grp_last;
480
481 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
482 cached_data->nntp_flags_directory,
483 ancestor_data->nntp_group_name, FLAGS_NAME);
484
485 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
486 if (r < 0) {
487 res = MAIL_ERROR_MEMORY;
488 goto err;
489 }
490
491 mmapstr = mmap_string_new("");
492 if (mmapstr == NULL) {
493 res = MAIL_ERROR_MEMORY;
494 goto close_db_flags;
495 }
496
497 for(i = first ; i <= last ; i++) {
498 struct mail_flags * flags;
499
500 r = nntpdriver_get_cached_flags(cache_db_flags, mmapstr,
501 i, &flags);
502 if (r == MAIL_NO_ERROR) {
503 if ((flags->fl_flags & MAIL_FLAG_CANCELLED) != 0) {
504 continue;
505 }
506
507 count ++;
508 if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) {
509 recent ++;
510 }
511 if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) {
512 unseen ++;
513 }
514 mail_flags_free(flags);
515 }
516 }
517
518 if ((count == 0) && (first != last)) {
519 count = last - first + 1;
520 recent = count;
521 unseen = count;
522 }
523
524 additionnal = ancestor_data->nntp_group_info->grp_last - last;
525 recent += additionnal;
526 unseen += additionnal;
527
528 mmap_string_free(mmapstr);
529 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
530
531 * result_messages = count;
532 * result_recent = recent;
533 * result_unseen = unseen;
534
535 return MAIL_NO_ERROR;
536
537 close_db_flags:
538 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
539 err:
540 return res;
541}
542
543static int nntpdriver_cached_messages_number(mailsession * session,
544 char * mb,
545 uint32_t * result)
546{
547 uint32_t messages;
548 uint32_t recent;
549 uint32_t unseen;
550 int r;
551
552 r = nntpdriver_cached_status_folder(session, mb,
553 &messages, &recent, &unseen);
554 if (r != MAIL_NO_ERROR)
555 return r;
556
557 * result = messages;
558
559 return MAIL_NO_ERROR;
560}
561
562static int nntpdriver_cached_recent_number(mailsession * session,
563 char * mb,
564 uint32_t * result)
565{
566 uint32_t messages;
567 uint32_t recent;
568 uint32_t unseen;
569 int r;
570
571 r = nntpdriver_cached_status_folder(session, mb,
572 &messages, &recent, &unseen);
573 if (r != MAIL_NO_ERROR)
574 return r;
575
576 * result = recent;
577
578 return MAIL_NO_ERROR;
579}
580
581static int nntpdriver_cached_unseen_number(mailsession * session,
582 char * mb,
583 uint32_t * result)
584{
585 uint32_t messages;
586 uint32_t recent;
587 uint32_t unseen;
588 int r;
589
590 r = nntpdriver_cached_status_folder(session, mb,
591 &messages, &recent, &unseen);
592 if (r != MAIL_NO_ERROR)
593 return r;
594
595 * result = unseen;
596
597 return MAIL_NO_ERROR;
598}
599
600static int nntpdriver_cached_list_folders(mailsession * session, char * mb,
601 struct mail_list ** result)
602{
603 return mailsession_list_folders(get_ancestor(session), mb, result);
604}
605
606static int nntpdriver_cached_lsub_folders(mailsession * session, char * mb,
607 struct mail_list ** result)
608{
609 return mailsession_lsub_folders(get_ancestor(session), mb, result);
610}
611
612static int nntpdriver_cached_subscribe_folder(mailsession * session,
613 char * mb)
614{
615 return mailsession_subscribe_folder(get_ancestor(session), mb);
616}
617
618static int nntpdriver_cached_unsubscribe_folder(mailsession * session,
619 char * mb)
620{
621 return mailsession_unsubscribe_folder(get_ancestor(session), mb);
622}
623
624
625
626/* messages operations */
627
628static int nntpdriver_cached_append_message(mailsession * session,
629 char * message, size_t size)
630{
631 return mailsession_append_message(get_ancestor(session), message, size);
632}
633
634
635
636static int
637get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
638 mailsession * session, uint32_t num,
639 struct mailimf_fields ** result)
640{
641 char keyname[PATH_MAX];
642 int r;
643 struct mailimf_fields * fields;
644 int res;
645
646 snprintf(keyname, PATH_MAX, "%i-envelope", num);
647
648 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields);
649 if (r != MAIL_NO_ERROR) {
650 res = r;
651 goto err;
652 }
653
654 * result = fields;
655
656 return MAIL_NO_ERROR;
657
658 err:
659 return res;
660}
661
662static int
663write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
664 mailsession * session, uint32_t num,
665 struct mailimf_fields * fields)
666{
667 int r;
668 int res;
669 char keyname[PATH_MAX];
670
671 snprintf(keyname, PATH_MAX, "%i-envelope", num);
672
673 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields);
674 if (r != MAIL_NO_ERROR) {
675 res = r;
676 goto err;
677 }
678
679 return MAIL_NO_ERROR;
680
681 err:
682 return res;
683}
684
685#define SEQ_FILENAME "articles-seq"
686
687static void read_article_seq(mailsession * session,
688 uint32_t * pfirst, uint32_t * plast)
689{
690 FILE * f;
691 struct nntp_session_state_data * ancestor_data;
692 uint32_t first;
693 uint32_t last;
694 char seq_filename[PATH_MAX];
695 struct nntp_cached_session_state_data * cached_data;
696 int r;
697
698 first = 0;
699 last = 0;
700
701 cached_data = get_cached_data(session);
702 ancestor_data = get_ancestor_data(session);
703
704 if (ancestor_data->nntp_group_name == NULL)
705 return;
706
707 snprintf(seq_filename, PATH_MAX, "%s/%s/%s",
708 cached_data->nntp_cache_directory,
709 ancestor_data->nntp_group_name, SEQ_FILENAME);
710 f = fopen(seq_filename, "r");
711
712 if (f != NULL) {
713 int fd;
714
715 fd = fileno(f);
716
717 r = maillock_read_lock(seq_filename, fd);
718 if (r == 0) {
719 MMAPString * mmapstr;
720 size_t cur_token;
721 char buf[sizeof(uint32_t) * 2];
722 size_t read_size;
723
724 read_size = fread(buf, 1, sizeof(uint32_t) * 2, f);
725 mmapstr = mmap_string_new_len(buf, read_size);
726 if (mmapstr != NULL) {
727 cur_token = 0;
728 r = mailimf_cache_int_read(mmapstr, &cur_token, &first);
729 r = mailimf_cache_int_read(mmapstr, &cur_token, &last);
730
731 mmap_string_free(mmapstr);
732 }
733
734 maillock_read_unlock(seq_filename, fd);
735 }
736 fclose(f);
737 }
738
739 * pfirst = first;
740 * plast = last;
741}
742
743static void write_article_seq(mailsession * session,
744 uint32_t first, uint32_t last)
745{
746 FILE * f;
747 struct nntp_session_state_data * ancestor_data;
748 char seq_filename[PATH_MAX];
749 struct nntp_cached_session_state_data * cached_data;
750 int r;
751 int fd;
752
753 cached_data = get_cached_data(session);
754 ancestor_data = get_ancestor_data(session);
755
756 if (ancestor_data->nntp_group_name == NULL)
757 return;
758
759 snprintf(seq_filename, PATH_MAX, "%s/%s/%s",
760 cached_data->nntp_cache_directory,
761 ancestor_data->nntp_group_name, SEQ_FILENAME);
762
763 fd = creat(seq_filename, S_IRUSR | S_IWUSR);
764 if (fd < 0)
765 return;
766
767 f = fdopen(fd, "w");
768 if (f != NULL) {
769 r = maillock_write_lock(seq_filename, fd);
770 if (r == 0) {
771 MMAPString * mmapstr;
772 size_t cur_token;
773
774 mmapstr = mmap_string_new("");
775 if (mmapstr != NULL) {
776 r = mail_serialize_clear(mmapstr, &cur_token);
777 if (r == MAIL_NO_ERROR) {
778 r = mailimf_cache_int_write(mmapstr, &cur_token, first);
779 r = mailimf_cache_int_write(mmapstr, &cur_token, last);
780
781 fwrite(mmapstr->str, 1, mmapstr->len, f);
782 }
783
784 mmap_string_free(mmapstr);
785 }
786
787 maillock_write_unlock(seq_filename, fd);
788 }
789 fclose(f);
790 }
791 else
792 close(fd);
793}
794
795
796static void get_uid_from_filename(char * filename)
797{
798 char * p;
799
800 if (strcmp(filename, SEQ_FILENAME) == 0)
801 * filename = 0;
802
803 p = strstr(filename, "-header");
804 if (p != NULL)
805 * p = 0;
806}
807
808static int
809nntpdriver_cached_get_envelopes_list(mailsession * session,
810 struct mailmessage_list * env_list)
811{
812 int r;
813 unsigned int i;
814 struct nntp_cached_session_state_data * cached_data;
815 uint32_t first;
816 uint32_t last;
817 struct nntp_session_state_data * ancestor_data;
818 char filename_env[PATH_MAX];
819 char filename_flags[PATH_MAX];
820 struct mail_cache_db * cache_db_env;
821 struct mail_cache_db * cache_db_flags;
822 MMAPString * mmapstr;
823 int res;
824 char cache_dir[PATH_MAX];
825
826 cached_data = get_cached_data(session);
827 ancestor_data = get_ancestor_data(session);
828
829 nntp_flags_store_process(cached_data->nntp_flags_directory,
830 ancestor_data->nntp_group_name,
831 cached_data->nntp_flags_store);
832
833 if (ancestor_data->nntp_group_name == NULL) {
834 res = MAIL_ERROR_BAD_STATE;
835 goto err;
836 }
837
838 /* read articles sequence */
839
840 read_article_seq(session, &first, &last);
841
842 mmapstr = mmap_string_new("");
843 if (mmapstr == NULL) {
844 res = MAIL_ERROR_MEMORY;
845 goto err;
846 }
847
848 snprintf(filename_env, PATH_MAX, "%s/%s/%s",
849 cached_data->nntp_cache_directory,
850 ancestor_data->nntp_group_name, ENV_NAME);
851
852 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
853 if (r < 0) {
854 res = MAIL_ERROR_MEMORY;
855 goto free_mmapstr;
856 }
857
858 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
859 cached_data->nntp_flags_directory,
860 ancestor_data->nntp_group_name, FLAGS_NAME);
861
862 /* fill with cached */
863
864 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
865 mailmessage * msg;
866 struct mailimf_fields * fields;
867
868 msg = carray_get(env_list->msg_tab, i);
869
870 if ((msg->msg_index < first) || (msg->msg_index > last))
871 continue;
872
873 if (msg->msg_fields == NULL) {
874 r = get_cached_envelope(cache_db_env, mmapstr,
875 session, msg->msg_index, &fields);
876 if (r == MAIL_NO_ERROR) {
877 msg->msg_fields = fields;
878 msg->msg_cached = TRUE;
879 }
880 }
881 }
882
883 mail_cache_db_close_unlock(filename_env, cache_db_env);
884
885 r = mailsession_get_envelopes_list(get_ancestor(session), env_list);
886
887 if (r != MAIL_NO_ERROR) {
888 res = r;
889 goto free_mmapstr;
890 }
891
892 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
893 if (r < 0) {
894 res = MAIL_ERROR_MEMORY;
895 goto free_mmapstr;
896 }
897
898 /* add flags */
899
900 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
901 mailmessage * msg;
902
903 msg = carray_get(env_list->msg_tab, i);
904
905 if (msg->msg_flags == NULL) {
906 struct mail_flags * flags;
907
908 r = nntpdriver_get_cached_flags(cache_db_flags, mmapstr,
909 msg->msg_index, &flags);
910 if (r == MAIL_NO_ERROR) {
911 msg->msg_flags = flags;
912 }
913 else {
914 msg->msg_flags = mail_flags_new_empty();
915 if (msg->msg_fields == NULL) {
916 msg->msg_flags->fl_flags |= MAIL_FLAG_CANCELLED;
917 mailmessage_check(msg);
918 }
919 }
920 }
921 }
922
923 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
924
925 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
926 if (r < 0) {
927 res = MAIL_ERROR_MEMORY;
928 goto free_mmapstr;
929 }
930
931 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
932 if (r < 0) {
933 res = MAIL_ERROR_MEMORY;
934 goto close_db_env;
935 }
936
937 /* must write cache */
938
939 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
940 mailmessage * msg;
941
942 msg = carray_get(env_list->msg_tab, i);
943
944 if (msg->msg_fields != NULL) {
945 if (!msg->msg_cached) {
946 r = write_cached_envelope(cache_db_env, mmapstr,
947 session, msg->msg_index, msg->msg_fields);
948 }
949 }
950
951 if (msg->msg_flags != NULL) {
952 r = nntpdriver_write_cached_flags(cache_db_flags, mmapstr,
953 msg->msg_index, msg->msg_flags);
954 }
955 }
956
957 first = 0;
958 last = 0;
959 if (carray_count(env_list->msg_tab) > 0) {
960 mailmessage * msg;
961
962 msg = carray_get(env_list->msg_tab, 0);
963 first = msg->msg_index;
964
965 msg = carray_get(env_list->msg_tab, carray_count(env_list->msg_tab) - 1);
966 last = msg->msg_index;
967 }
968
969 /* write articles sequence */
970
971 write_article_seq(session, first, last);
972
973 /* flush cache */
974
975 maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list);
976
977 /* remove cache files */
978
979 snprintf(cache_dir, PATH_MAX, "%s/%s",
980 cached_data->nntp_cache_directory, ancestor_data->nntp_group_name);
981
982 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
983 mail_cache_db_close_unlock(filename_env, cache_db_env);
984 mmap_string_free(mmapstr);
985
986 maildriver_message_cache_clean_up(cache_dir, env_list,
987 get_uid_from_filename);
988
989 return MAIL_NO_ERROR;
990
991 close_db_env:
992 mail_cache_db_close_unlock(filename_env, cache_db_env);
993 free_mmapstr:
994 mmap_string_free(mmapstr);
995 err:
996 return res;
997}
998
999static int
1000nntpdriver_cached_get_messages_list(mailsession * session,
1001 struct mailmessage_list ** result)
1002{
1003 return nntp_get_messages_list(get_ancestor(session), session,
1004 nntp_cached_message_driver, result);
1005}
1006
1007static int nntpdriver_cached_get_message(mailsession * session,
1008 uint32_t num, mailmessage ** result)
1009{
1010 mailmessage * msg_info;
1011 int r;
1012
1013 msg_info = mailmessage_new();
1014 if (msg_info == NULL)
1015 return MAIL_ERROR_MEMORY;
1016
1017 r = mailmessage_init(msg_info, session, nntp_cached_message_driver, num, 0);
1018 if (r != MAIL_NO_ERROR) {
1019 mailmessage_free(msg_info);
1020 return r;
1021 }
1022
1023 * result = msg_info;
1024
1025 return MAIL_NO_ERROR;
1026}
1027
1028static int nntpdriver_cached_noop(mailsession * session)
1029{
1030 return mailsession_noop(get_ancestor(session));
1031}
1032
1033static int nntpdriver_cached_get_message_by_uid(mailsession * session,
1034 const char * uid,
1035 mailmessage ** result)
1036{
1037 uint32_t num;
1038 char * p;
1039
1040 if (uid == NULL)
1041 return MAIL_ERROR_INVAL;
1042
1043 num = strtoul(uid, &p, 10);
1044 if ((p == uid) || (* p != '\0'))
1045 return MAIL_ERROR_INVAL;
1046
1047 return nntpdriver_cached_get_message(session, num, result);
1048}
diff --git a/kmicromail/libetpan/generic/nntpdriver_cached.h b/kmicromail/libetpan/generic/nntpdriver_cached.h
new file mode 100644
index 0000000..feb576b
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_cached.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NNTPDRIVER_CACHED_H
37
38#define NNTPDRIVER_CACHED_H
39
40#include <libetpan/nntpdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * nntp_cached_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/nntpdriver_cached_message.c b/kmicromail/libetpan/generic/nntpdriver_cached_message.c
new file mode 100644
index 0000000..a2bb6f7
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_cached_message.c
@@ -0,0 +1,365 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "nntpdriver_cached_message.h"
37
38#include <string.h>
39#include <stdlib.h>
40
41#include "mail_cache_db.h"
42
43#include "mailmessage.h"
44#include "mailmessage_tools.h"
45#include "nntpdriver.h"
46#include "nntpdriver_tools.h"
47#include "nntpdriver_cached.h"
48#include "nntpdriver_message.h"
49#include "generic_cache.h"
50
51static int nntp_prefetch(mailmessage * msg_info);
52
53static void nntp_prefetch_free(struct generic_message_t * msg);
54
55static int nntp_initialize(mailmessage * msg_info);
56
57static int nntp_fetch_header(mailmessage * msg_info,
58 char ** result,
59 size_t * result_len);
60
61static int nntp_fetch_size(mailmessage * msg_info,
62 size_t * result);
63
64static void nntp_uninitialize(mailmessage * msg_info);
65
66static void nntp_flush(mailmessage * msg_info);
67
68static void nntp_check(mailmessage * msg_info);
69
70static int nntp_get_flags(mailmessage * msg_info,
71 struct mail_flags ** result);
72
73static mailmessage_driver local_nntp_cached_message_driver = {
74 .msg_name = "nntp-cached",
75
76 .msg_initialize = nntp_initialize,
77 .msg_uninitialize = nntp_uninitialize,
78
79 .msg_flush = nntp_flush,
80 .msg_check = nntp_check,
81
82 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
83
84 .msg_fetch = mailmessage_generic_fetch,
85 .msg_fetch_header = nntp_fetch_header,
86 .msg_fetch_body = mailmessage_generic_fetch_body,
87 .msg_fetch_size = nntp_fetch_size,
88 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
89 .msg_fetch_section = mailmessage_generic_fetch_section,
90 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
91 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
92 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
93 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
94
95 .msg_get_flags = nntp_get_flags,
96};
97
98mailmessage_driver * nntp_cached_message_driver =
99&local_nntp_cached_message_driver;
100
101static inline struct nntp_cached_session_state_data *
102get_cached_session_data(mailmessage * msg)
103{
104 return msg->msg_session->sess_data;
105}
106
107static inline mailsession * get_ancestor_session(mailmessage * msg)
108{
109 return get_cached_session_data(msg)->nntp_ancestor;
110}
111
112static inline struct nntp_session_state_data *
113get_ancestor_session_data(mailmessage * msg)
114{
115 return get_ancestor_session(msg)->sess_data;
116}
117
118static inline newsnntp *
119get_nntp_session(mailmessage * msg)
120{
121 return get_ancestor_session_data(msg)->nntp_session;
122}
123
124static int nntp_prefetch(mailmessage * msg_info)
125{
126 char * msg_content;
127 size_t msg_length;
128 struct generic_message_t * msg;
129 int r;
130 struct nntp_cached_session_state_data * cached_data;
131 struct nntp_session_state_data * ancestor_data;
132 char filename[PATH_MAX];
133
134 /* we try the cached message */
135
136 cached_data = get_cached_session_data(msg_info);
137
138 ancestor_data = get_ancestor_session_data(msg_info);
139
140 snprintf(filename, PATH_MAX, "%s/%s/%i", cached_data->nntp_cache_directory,
141 ancestor_data->nntp_group_name, msg_info->msg_index);
142
143 r = generic_cache_read(filename, &msg_content, &msg_length);
144 if (r == MAIL_NO_ERROR) {
145 msg = msg_info->msg_data;
146
147 msg->msg_message = msg_content;
148 msg->msg_length = msg_length;
149
150 return MAIL_NO_ERROR;
151 }
152
153 /* we get the message through the network */
154
155 r = nntpdriver_article(get_ancestor_session(msg_info),
156 msg_info->msg_index, &msg_content,
157 &msg_length);
158
159 if (r != MAIL_NO_ERROR)
160 return r;
161
162 /* we write the message cache */
163
164 generic_cache_store(filename, msg_content, msg_length);
165
166 msg = msg_info->msg_data;
167
168 msg->msg_message = msg_content;
169 msg->msg_length = msg_length;
170
171 return MAIL_NO_ERROR;
172}
173
174static void nntp_prefetch_free(struct generic_message_t * msg)
175{
176 if (msg->msg_message != NULL) {
177 mmap_string_unref(msg->msg_message);
178 msg->msg_message = NULL;
179 }
180}
181
182static int nntp_initialize(mailmessage * msg_info)
183{
184 struct generic_message_t * msg;
185 int r;
186 char * uid;
187 char static_uid[20];
188
189 snprintf(static_uid, 20, "%u", msg_info->msg_index);
190 uid = strdup(static_uid);
191 if (uid == NULL)
192 return MAIL_ERROR_MEMORY;
193
194 r = mailmessage_generic_initialize(msg_info);
195 if (r != MAIL_NO_ERROR) {
196 free(uid);
197 return r;
198 }
199
200 msg = msg_info->msg_data;
201 msg->msg_prefetch = nntp_prefetch;
202 msg->msg_prefetch_free = nntp_prefetch_free;
203 msg_info->msg_uid = uid;
204
205 return MAIL_NO_ERROR;
206}
207
208
209static void nntp_uninitialize(mailmessage * msg_info)
210{
211 mailmessage_generic_uninitialize(msg_info);
212}
213
214#define FLAGS_NAME "flags.db"
215
216static void nntp_flush(mailmessage * msg_info)
217{
218 mailmessage_generic_flush(msg_info);
219}
220
221
222static void nntp_check(mailmessage * msg_info)
223{
224 int r;
225
226 if (msg_info->msg_flags != NULL) {
227 r = mail_flags_store_set(get_cached_session_data(msg_info)->nntp_flags_store,
228 msg_info);
229 /* ignore errors */
230 }
231}
232
233static int nntp_fetch_header(mailmessage * msg_info,
234 char ** result,
235 size_t * result_len)
236{
237 struct generic_message_t * msg;
238 char * headers;
239 size_t headers_length;
240 struct nntp_cached_session_state_data * cached_data;
241 struct nntp_session_state_data * ancestor_data;
242 int r;
243 char filename[PATH_MAX];
244
245 msg = msg_info->msg_data;
246
247 if (msg->msg_message != NULL)
248 return mailmessage_generic_fetch_header(msg_info,
249 result, result_len);
250
251 /* we try the cached message */
252
253 cached_data = get_cached_session_data(msg_info);
254
255 ancestor_data = get_ancestor_session_data(msg_info);
256
257 snprintf(filename, PATH_MAX, "%s/%s/%i-header",
258 cached_data->nntp_cache_directory,
259 ancestor_data->nntp_group_name, msg_info->msg_index);
260
261 r = generic_cache_read(filename, &headers, &headers_length);
262 if (r == MAIL_NO_ERROR) {
263 * result = headers;
264 * result_len = headers_length;
265
266 return MAIL_NO_ERROR;
267 }
268
269 /* we get the message through the network */
270
271 r = nntpdriver_head(get_ancestor_session(msg_info), msg_info->msg_index,
272 &headers, &headers_length);
273 if (r != MAIL_NO_ERROR)
274 return r;
275
276 /* we write the message cache */
277
278 generic_cache_store(filename, headers, headers_length);
279
280 * result = headers;
281 * result_len = headers_length;
282
283 return MAIL_NO_ERROR;
284}
285
286static int nntp_fetch_size(mailmessage * msg_info,
287 size_t * result)
288{
289 return nntpdriver_size(get_ancestor_session(msg_info),
290 msg_info->msg_index, result);
291}
292
293static int nntp_get_flags(mailmessage * msg_info,
294 struct mail_flags ** result)
295{
296 int r;
297 struct mail_flags * flags;
298 struct mail_cache_db * cache_db_flags;
299 char filename_flags[PATH_MAX];
300 int res;
301 MMAPString * mmapstr;
302
303 if (msg_info->msg_flags != NULL) {
304 * result = msg_info->msg_flags;
305
306 return MAIL_NO_ERROR;
307 }
308
309 flags = mail_flags_store_get(get_cached_session_data(msg_info)->nntp_flags_store, msg_info->msg_index);
310
311 if (flags == NULL) {
312 struct nntp_cached_session_state_data * cached_data;
313 struct nntp_session_state_data * ancestor_data;
314
315 cached_data = get_cached_session_data(msg_info);
316
317 ancestor_data = get_ancestor_session_data(msg_info);
318 if (ancestor_data->nntp_group_name == NULL) {
319 res = MAIL_ERROR_BAD_STATE;
320 goto err;
321 }
322
323 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
324 cached_data->nntp_flags_directory,
325 ancestor_data->nntp_group_name, FLAGS_NAME);
326
327 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
328 if (r < 0) {
329 res = MAIL_ERROR_MEMORY;
330 goto err;
331 }
332
333 mmapstr = mmap_string_new("");
334 if (mmapstr == NULL) {
335 res = MAIL_ERROR_MEMORY;
336 goto close_db_flags;
337 }
338
339 r = nntpdriver_get_cached_flags(cache_db_flags, mmapstr,
340 msg_info->msg_index, &flags);
341 if (r != MAIL_NO_ERROR) {
342 flags = mail_flags_new_empty();
343 if (flags == NULL) {
344 res = MAIL_ERROR_MEMORY;
345 goto free_mmapstr;
346 }
347 }
348
349 mmap_string_free(mmapstr);
350 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
351 }
352
353 msg_info->msg_flags = flags;
354
355 * result = flags;
356
357 return MAIL_NO_ERROR;
358
359 free_mmapstr:
360 mmap_string_free(mmapstr);
361 close_db_flags:
362 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
363 err:
364 return res;
365}
diff --git a/kmicromail/libetpan/generic/nntpdriver_cached_message.h b/kmicromail/libetpan/generic/nntpdriver_cached_message.h
new file mode 100644
index 0000000..c12f479
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_cached_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include <libetpan/mailmessage_types.h>
37
38#ifndef NNTPDRIVER_CACHED_MESSAGE_H
39
40#define NNTPDRIVER_CACHED_MESSAGE_H
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * nntp_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/nntpdriver_message.c b/kmicromail/libetpan/generic/nntpdriver_message.c
new file mode 100644
index 0000000..47b11ec
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_message.c
@@ -0,0 +1,169 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "nntpdriver_message.h"
37
38#include "mailmessage_tools.h"
39#include "nntpdriver_tools.h"
40#include "nntpdriver.h"
41#include "newsnntp.h"
42#include <string.h>
43#include <stdlib.h>
44
45static int nntp_prefetch(mailmessage * msg_info);
46
47static void nntp_prefetch_free(struct generic_message_t * msg);
48
49static int nntp_initialize(mailmessage * msg_info);
50
51static int nntp_fetch_header(mailmessage * msg_info,
52 char ** result,
53 size_t * result_len);
54
55static int nntp_fetch_size(mailmessage * msg_info,
56 size_t * result);
57
58static mailmessage_driver local_nntp_message_driver = {
59 .msg_name = "nntp",
60
61 .msg_initialize = nntp_initialize,
62 .msg_uninitialize = mailmessage_generic_uninitialize,
63
64 .msg_flush = mailmessage_generic_flush,
65 .msg_check = NULL,
66
67 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
68
69 .msg_fetch = mailmessage_generic_fetch,
70 .msg_fetch_header = nntp_fetch_header,
71 .msg_fetch_body = mailmessage_generic_fetch_body,
72 .msg_fetch_size = nntp_fetch_size,
73 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
74 .msg_fetch_section = mailmessage_generic_fetch_section,
75 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
76 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
77 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
78 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
79
80 .msg_get_flags = NULL,
81};
82
83mailmessage_driver * nntp_message_driver = &local_nntp_message_driver;
84
85static int nntp_prefetch(mailmessage * msg_info)
86{
87 char * msg_content;
88 size_t msg_length;
89 struct generic_message_t * msg;
90 int r;
91
92 r = nntpdriver_article(msg_info->msg_session, msg_info->msg_index,
93 &msg_content, &msg_length);
94 if (r != MAIL_NO_ERROR)
95 return r;
96
97 msg = msg_info->msg_data;
98
99 msg->msg_message = msg_content;
100 msg->msg_length = msg_length;
101
102 return MAIL_NO_ERROR;
103}
104
105static void nntp_prefetch_free(struct generic_message_t * msg)
106{
107 if (msg->msg_message != NULL) {
108 mmap_string_unref(msg->msg_message);
109 msg->msg_message = NULL;
110 }
111}
112
113static int nntp_initialize(mailmessage * msg_info)
114{
115 struct generic_message_t * msg;
116 int r;
117 char * uid;
118 char static_uid[20];
119
120 snprintf(static_uid, 20, "%u", msg_info->msg_index);
121 uid = strdup(static_uid);
122 if (uid == NULL)
123 return MAIL_ERROR_MEMORY;
124
125 r = mailmessage_generic_initialize(msg_info);
126 if (r != MAIL_NO_ERROR) {
127 free(uid);
128 return r;
129 }
130
131 msg = msg_info->msg_data;
132 msg->msg_prefetch = nntp_prefetch;
133 msg->msg_prefetch_free = nntp_prefetch_free;
134 msg_info->msg_uid = uid;
135
136 return MAIL_NO_ERROR;
137}
138
139static int nntp_fetch_header(mailmessage * msg_info,
140 char ** result,
141 size_t * result_len)
142{
143 struct generic_message_t * msg;
144 char * headers;
145 size_t headers_length;
146 int r;
147
148 msg = msg_info->msg_data;
149
150 if (msg->msg_message != NULL)
151 return mailmessage_generic_fetch_header(msg_info,
152 result, result_len);
153
154 r = nntpdriver_head(msg_info->msg_session, msg_info->msg_index,
155 &headers, &headers_length);
156 if (r != MAIL_NO_ERROR)
157 return r;
158
159 * result = headers;
160 * result_len = headers_length;
161
162 return MAIL_NO_ERROR;
163}
164
165static int nntp_fetch_size(mailmessage * msg_info,
166 size_t * result)
167{
168 return nntpdriver_size(msg_info->msg_session, msg_info->msg_index, result);
169}
diff --git a/kmicromail/libetpan/generic/nntpdriver_message.h b/kmicromail/libetpan/generic/nntpdriver_message.h
new file mode 100644
index 0000000..3b12a2d
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NNTPDRIVER_MESSAGE_H
37
38#define NNTPDRIVER_MESSAGE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/nntpdriver_types.h>
45
46extern mailmessage_driver * nntp_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/nntpdriver_tools.c b/kmicromail/libetpan/generic/nntpdriver_tools.c
new file mode 100644
index 0000000..26be916
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_tools.c
@@ -0,0 +1,563 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "nntpdriver_tools.h"
37
38#include "mail.h"
39#include "nntpdriver.h"
40#include "nntpdriver_cached.h"
41#include "newsnntp.h"
42#include "maildriver_types.h"
43#include "generic_cache.h"
44#include "imfcache.h"
45#include "mailmessage.h"
46#include "mail_cache_db.h"
47
48#include <sys/types.h>
49#include <sys/stat.h>
50#include <fcntl.h>
51#include <unistd.h>
52#include <string.h>
53#include <stdlib.h>
54
55int nntpdriver_nntp_error_to_mail_error(int error)
56{
57 switch (error) {
58 case NEWSNNTP_NO_ERROR:
59 return MAIL_NO_ERROR;
60
61 case NEWSNNTP_ERROR_STREAM:
62 return MAIL_ERROR_STREAM;
63
64 case NEWSNNTP_ERROR_UNEXPECTED:
65 return MAIL_ERROR_PROGRAM_ERROR;
66
67 case NEWSNNTP_ERROR_NO_NEWSGROUP_SELECTED:
68 return MAIL_ERROR_FOLDER_NOT_FOUND;
69
70 case NEWSNNTP_ERROR_NO_ARTICLE_SELECTED:
71 case NEWSNNTP_ERROR_INVALID_ARTICLE_NUMBER:
72 case NEWSNNTP_ERROR_ARTICLE_NOT_FOUND:
73 return MAIL_ERROR_MSG_NOT_FOUND;
74
75 case NEWSNNTP_ERROR_UNEXPECTED_RESPONSE:
76 case NEWSNNTP_ERROR_INVALID_RESPONSE:
77 return MAIL_ERROR_PARSE;
78
79 case NEWSNNTP_ERROR_NO_SUCH_NEWS_GROUP:
80 return MAIL_ERROR_FOLDER_NOT_FOUND;
81
82 case NEWSNNTP_ERROR_POSTING_NOT_ALLOWED:
83 return MAIL_ERROR_READONLY;
84
85 case NEWSNNTP_ERROR_POSTING_FAILED:
86 return MAIL_ERROR_APPEND;
87
88 case NEWSNNTP_ERROR_PROGRAM_ERROR:
89 return MAIL_ERROR_PROGRAM_ERROR;
90
91 case NEWSNNTP_ERROR_NO_PERMISSION:
92 return MAIL_ERROR_NO_PERMISSION;
93
94 case NEWSNNTP_ERROR_COMMAND_NOT_UNDERSTOOD:
95 case NEWSNNTP_ERROR_COMMAND_NOT_SUPPORTED:
96 return MAIL_ERROR_COMMAND_NOT_SUPPORTED;
97
98 case NEWSNNTP_ERROR_CONNECTION_REFUSED:
99 return MAIL_ERROR_CONNECT;
100
101 case NEWSNNTP_ERROR_MEMORY:
102 return MAIL_ERROR_MEMORY;
103
104 case NEWSNNTP_ERROR_AUTHENTICATION_REJECTED:
105 return MAIL_ERROR_LOGIN;
106
107 case NEWSNNTP_ERROR_BAD_STATE:
108 return MAIL_ERROR_BAD_STATE;
109
110 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
111 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
112 default:
113 return MAIL_ERROR_INVAL;
114 }
115}
116
117static inline struct nntp_session_state_data *
118session_get_data(mailsession * session)
119{
120 return session->sess_data;
121}
122
123static inline newsnntp * session_get_nntp_session(mailsession * session)
124{
125 return session_get_data(session)->nntp_session;
126}
127
128static inline struct nntp_cached_session_state_data *
129cached_session_get_data(mailsession * session)
130{
131 return session->sess_data;
132}
133
134static inline mailsession * cached_session_get_ancestor(mailsession * session)
135{
136 return cached_session_get_data(session)->nntp_ancestor;
137}
138
139static inline struct nntp_session_state_data *
140cached_session_get_ancestor_data(mailsession * session)
141{
142 return session_get_data(cached_session_get_ancestor(session));
143}
144
145static inline newsnntp * cached_session_get_nntp_session(mailsession * session)
146{
147 return session_get_nntp_session(cached_session_get_ancestor(session));
148}
149
150
151int nntpdriver_authenticate_password(mailsession * session)
152{
153 struct nntp_session_state_data * data;
154 int r;
155
156 data = session_get_data(session);
157
158 if (data->nntp_password == NULL)
159 return MAIL_ERROR_LOGIN;
160
161 r = newsnntp_authinfo_password(session_get_nntp_session(session),
162 data->nntp_password);
163
164 return nntpdriver_nntp_error_to_mail_error(r);
165}
166
167int nntpdriver_mode_reader(mailsession * session)
168{
169 int done;
170 int r;
171
172 done = FALSE;
173
174 do {
175 r = newsnntp_mode_reader(session_get_nntp_session(session));
176
177 switch (r) {
178 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
179 r = nntpdriver_authenticate_user(session);
180 if (r != MAIL_NO_ERROR)
181 return r;
182 break;
183
184 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
185 r = nntpdriver_authenticate_password(session);
186 if (r != MAIL_NO_ERROR)
187 return r;
188 break;
189
190 case NEWSNNTP_NO_ERROR:
191 done = TRUE;
192 break;
193
194 default:
195 done = TRUE;
196 break;
197 }
198 }
199 while (!done);
200
201 return MAIL_NO_ERROR;
202}
203
204int nntpdriver_authenticate_user(mailsession * session)
205{
206 struct nntp_session_state_data * data;
207 int r;
208
209 data = session_get_data(session);
210
211 if (data->nntp_userid == NULL)
212 return MAIL_ERROR_LOGIN;
213
214 r = newsnntp_authinfo_username(session_get_nntp_session(session),
215 data->nntp_userid);
216
217 switch (r) {
218 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
219 return nntpdriver_authenticate_password(session);
220
221 default:
222 return nntpdriver_nntp_error_to_mail_error(r);
223 }
224}
225
226int nntpdriver_article(mailsession * session, uint32_t index,
227 char ** result,
228 size_t * result_len)
229{
230 char * msg_content;
231 size_t msg_length;
232 int r;
233 int done;
234
235 done = FALSE;
236 do {
237 r = newsnntp_article(session_get_nntp_session(session),
238 index, &msg_content, &msg_length);
239
240 switch (r) {
241 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
242 r = nntpdriver_authenticate_user(session);
243 if (r != MAIL_NO_ERROR)
244 return r;
245 break;
246
247 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
248 r = nntpdriver_authenticate_password(session);
249 if (r != MAIL_NO_ERROR)
250 return r;
251 break;
252
253 case NEWSNNTP_NO_ERROR:
254 done = TRUE;
255 break;
256
257 default:
258 return nntpdriver_nntp_error_to_mail_error(r);
259 }
260 }
261 while (!done);
262
263 * result = msg_content;
264 * result_len = msg_length;
265
266 return MAIL_NO_ERROR;
267}
268
269int nntpdriver_head(mailsession * session, uint32_t index,
270 char ** result,
271 size_t * result_len)
272{
273 char * headers;
274 size_t headers_length;
275 int r;
276 int done;
277
278 done = FALSE;
279 do {
280 r = newsnntp_head(session_get_nntp_session(session),
281 index, &headers, &headers_length);
282
283 switch (r) {
284 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
285 r = nntpdriver_authenticate_user(session);
286 if (r != MAIL_NO_ERROR)
287 return r;
288 break;
289
290 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
291 r = nntpdriver_authenticate_password(session);
292 if (r != MAIL_NO_ERROR)
293 return r;
294 break;
295
296 case NEWSNNTP_NO_ERROR:
297 done = TRUE;
298 break;
299
300 default:
301 return nntpdriver_nntp_error_to_mail_error(r);
302 }
303 }
304 while (!done);
305
306 * result = headers;
307 * result_len = headers_length;
308
309 return MAIL_NO_ERROR;
310}
311
312int nntpdriver_size(mailsession * session, uint32_t index,
313 size_t * result)
314{
315 newsnntp * nntp;
316 struct newsnntp_xover_resp_item * item;
317 int r;
318 int done;
319
320 nntp = session_get_nntp_session(session);
321
322 done = FALSE;
323 do {
324 r = newsnntp_xover_single(nntp, index, &item);
325 switch (r) {
326 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
327 r = nntpdriver_authenticate_user(session);
328 if (r != MAIL_NO_ERROR)
329 return r;
330 break;
331
332 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
333 r = nntpdriver_authenticate_password(session);
334 if (r != MAIL_NO_ERROR)
335 return r;
336 break;
337
338 case NEWSNNTP_NO_ERROR:
339 done = TRUE;
340 break;
341
342 default:
343 return nntpdriver_nntp_error_to_mail_error(r);
344 }
345 }
346 while (!done);
347
348 * result = item->ovr_size;
349
350 xover_resp_item_free(item);
351
352 return MAIL_NO_ERROR;
353}
354
355int
356nntpdriver_get_cached_flags(struct mail_cache_db * cache_db,
357 MMAPString * mmapstr,
358 uint32_t num,
359 struct mail_flags ** result)
360{
361 int r;
362 char keyname[PATH_MAX];
363 struct mail_flags * flags;
364 int res;
365
366 snprintf(keyname, PATH_MAX, "%u-flags", num);
367
368 r = generic_cache_flags_read(cache_db, mmapstr, keyname, &flags);
369 if (r != MAIL_NO_ERROR) {
370 res = r;
371 goto err;
372 }
373
374 * result = flags;
375
376 return MAIL_NO_ERROR;
377
378 err:
379 return res;
380}
381
382int
383nntpdriver_write_cached_flags(struct mail_cache_db * cache_db,
384 MMAPString * mmapstr,
385 uint32_t num,
386 struct mail_flags * flags)
387{
388 int r;
389 char keyname[PATH_MAX];
390 int res;
391
392 snprintf(keyname, PATH_MAX, "%u-flags", num);
393
394 r = generic_cache_flags_write(cache_db, mmapstr, keyname, flags);
395 if (r != MAIL_NO_ERROR) {
396 res = r;
397 goto err;
398 }
399
400 return MAIL_NO_ERROR;
401
402 err:
403 return res;
404}
405
406
407
408int nntpdriver_select_folder(mailsession * session, char * mb)
409{
410 int r;
411 struct newsnntp_group_info * info;
412 newsnntp * nntp_session;
413 struct nntp_session_state_data * data;
414 char * new_name;
415 int done;
416
417 data = session_get_data(session);
418
419 if (!data->nntp_mode_reader) {
420 r = nntpdriver_mode_reader(session);
421 if (r != MAIL_NO_ERROR)
422 return r;
423
424 data->nntp_mode_reader = TRUE;
425 }
426
427 if (data->nntp_group_name != NULL)
428 if (strcmp(data->nntp_group_name, mb) == 0)
429 return MAIL_NO_ERROR;
430
431 nntp_session = session_get_nntp_session(session);
432
433 done = FALSE;
434 do {
435 r = newsnntp_group(nntp_session, mb, &info);
436
437 switch (r) {
438 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
439 r = nntpdriver_authenticate_user(session);
440 if (r != MAIL_NO_ERROR)
441 return r;
442 break;
443
444 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
445 r = nntpdriver_authenticate_password(session);
446 if (r != MAIL_NO_ERROR)
447 return r;
448 break;
449
450 case NEWSNNTP_NO_ERROR:
451 done = TRUE;
452 break;
453
454 default:
455 return nntpdriver_nntp_error_to_mail_error(r);
456 }
457
458 }
459 while (!done);
460
461 new_name = strdup(mb);
462 if (new_name == NULL)
463 return MAIL_ERROR_MEMORY;
464
465 if (data->nntp_group_name != NULL)
466 free(data->nntp_group_name);
467 data->nntp_group_name = new_name;
468 if (data->nntp_group_info != NULL)
469 newsnntp_group_free(data->nntp_group_info);
470 data->nntp_group_info = info;
471
472 return MAIL_NO_ERROR;
473}
474
475
476int nntp_get_messages_list(mailsession * nntp_session,
477 mailsession * session,
478 mailmessage_driver * driver,
479 struct mailmessage_list ** result)
480{
481 carray * tab;
482 struct mailmessage_list * env_list;
483 uint32_t i;
484 int res;
485 int r;
486 struct nntp_session_state_data * data;
487 struct newsnntp_group_info * group_info;
488 uint32_t max;
489 unsigned int cur;
490
491 data = session_get_data(nntp_session);
492
493 if (data->nntp_group_name == NULL) {
494 res = MAIL_ERROR_BAD_STATE;
495 goto err;
496 }
497
498 r = nntpdriver_select_folder(nntp_session, data->nntp_group_name);
499 if (r != MAIL_NO_ERROR) {
500 res = r;
501 goto err;
502 }
503
504 group_info = data->nntp_group_info;
505
506 if (group_info == NULL) {
507 res = MAIL_ERROR_BAD_STATE;
508 goto err;
509 }
510
511 max = group_info->grp_first;
512 if (data->nntp_max_articles != 0) {
513 if (group_info->grp_last - data->nntp_max_articles + 1 > max)
514 max = group_info->grp_last - data->nntp_max_articles + 1;
515 }
516
517 tab = carray_new(128);
518 if (tab == NULL) {
519 res = MAIL_ERROR_MEMORY;
520 goto err;
521 }
522
523 for(i = max ; i <= group_info->grp_last ; i++) {
524 mailmessage * msg;
525
526 msg = mailmessage_new();
527 if (msg == NULL) {
528 res = MAIL_ERROR_MEMORY;
529 goto free_list;
530 }
531
532 r = mailmessage_init(msg, session, driver, i, 0);
533 if (r != MAIL_NO_ERROR) {
534 mailmessage_free(msg);
535 res = r;
536 goto free_list;
537 }
538
539 r = carray_add(tab, msg, NULL);
540 if (r < 0) {
541 mailmessage_free(msg);
542 res = MAIL_ERROR_MEMORY;
543 goto free_list;
544 }
545 }
546
547 env_list = mailmessage_list_new(tab);
548 if (env_list == NULL) {
549 res = MAIL_ERROR_MEMORY;
550 goto free_list;
551 }
552
553 * result = env_list;
554
555 return MAIL_NO_ERROR;
556
557 free_list:
558 for(cur = 0 ; cur < carray_count(tab) ; cur ++)
559 mailmessage_free(carray_get(tab, cur));
560 carray_free(tab);
561 err:
562 return res;
563}
diff --git a/kmicromail/libetpan/generic/nntpdriver_tools.h b/kmicromail/libetpan/generic/nntpdriver_tools.h
new file mode 100644
index 0000000..6b8aca5
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_tools.h
@@ -0,0 +1,88 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NNTPDRIVER_TOOLS_H
37
38#define NNTPDRIVER_TOOLS_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mail_cache_db_types.h"
45#include "nntpdriver_types.h"
46
47int nntpdriver_nntp_error_to_mail_error(int error);
48
49int nntpdriver_authenticate_password(mailsession * session);
50
51int nntpdriver_authenticate_user(mailsession * session);
52
53int nntpdriver_article(mailsession * session, uint32_t index,
54 char ** result, size_t * result_len);
55
56int nntpdriver_head(mailsession * session, uint32_t index,
57 char ** result,
58 size_t * result_len);
59
60int nntpdriver_size(mailsession * session, uint32_t index,
61 size_t * result);
62
63int
64nntpdriver_get_cached_flags(struct mail_cache_db * cache_db,
65 MMAPString * mmapstr,
66 uint32_t num,
67 struct mail_flags ** result);
68
69int
70nntpdriver_write_cached_flags(struct mail_cache_db * cache_db,
71 MMAPString * mmapstr,
72 uint32_t num,
73 struct mail_flags * flags);
74
75int nntpdriver_select_folder(mailsession * session, char * mb);
76
77int nntp_get_messages_list(mailsession * nntp_session,
78 mailsession * session,
79 mailmessage_driver * driver,
80 struct mailmessage_list ** result);
81
82int nntpdriver_mode_reader(mailsession * session);
83
84#ifdef __cplusplus
85}
86#endif
87
88#endif
diff --git a/kmicromail/libetpan/generic/nntpdriver_types.h b/kmicromail/libetpan/generic/nntpdriver_types.h
new file mode 100644
index 0000000..6492788
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver_types.h
@@ -0,0 +1,146 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NNTPDRIVER_TYPES_H
37
38#define NNTPDRIVER_TYPES_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/maildriver_types.h>
43#include <libetpan/newsnntp.h>
44#include <libetpan/clist.h>
45#include <libetpan/generic_cache_types.h>
46#include <libetpan/mailstorage_types.h>
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52/* NNTP driver for session */
53
54enum {
55 NNTPDRIVER_SET_MAX_ARTICLES = 1,
56};
57
58struct nntp_session_state_data {
59 newsnntp * nntp_session;
60 char * nntp_userid;
61 char * nntp_password;
62
63 struct newsnntp_group_info * nntp_group_info;
64 char * nntp_group_name;
65
66 clist * nntp_subscribed_list;
67
68 uint32_t nntp_max_articles;
69
70 int nntp_mode_reader;
71};
72
73/* cached NNTP driver for session */
74
75enum {
76 /* the mapping of the parameters should be the same as for nntp */
77 NNTPDRIVER_CACHED_SET_MAX_ARTICLES = 1,
78 /* cache specific */
79 NNTPDRIVER_CACHED_SET_CACHE_DIRECTORY,
80 NNTPDRIVER_CACHED_SET_FLAGS_DIRECTORY,
81};
82
83struct nntp_cached_session_state_data {
84 mailsession * nntp_ancestor;
85 char nntp_cache_directory[PATH_MAX];
86 char nntp_flags_directory[PATH_MAX];
87 struct mail_flags_store * nntp_flags_store;
88};
89
90
91/* nntp storage */
92
93/*
94 nntp_mailstorage is the state data specific to the IMAP4rev1 storage.
95
96 - storage this is the storage to initialize.
97
98 - servername this is the name of the NNTP server
99
100 - port is the port to connect to, on the server.
101 you give 0 to use the default port.
102
103 - connection_type is the type of socket layer to use.
104 The value can be CONNECTION_TYPE_PLAIN or CONNECTION_TYPE_TLS.
105
106 - auth_type is the authenticate mechanism to use.
107 The value can be NNTP_AUTH_TYPE_PLAIN.
108
109 - login is the login of the POP3 account.
110
111 - password is the password of the POP3 account.
112
113 - cached if this value is != 0, a persistant cache will be
114 stored on local system.
115
116 - cache_directory is the location of the cache
117
118 - flags_directory is the location of the flags
119*/
120
121struct nntp_mailstorage {
122 char * nntp_servername;
123 uint16_t nntp_port;
124 char * nntp_command;
125 int nntp_connection_type;
126
127 int nntp_auth_type;
128 char * nntp_login;
129 char * nntp_password;
130
131 int nntp_cached;
132 char * nntp_cache_directory;
133 char * nntp_flags_directory;
134};
135
136/* this is the type of NNTP authentication */
137
138enum {
139 NNTP_AUTH_TYPE_PLAIN, /* plain text authentication */
140};
141
142#ifdef __cplusplus
143}
144#endif
145
146#endif
diff --git a/kmicromail/libetpan/generic/nntpstorage.c b/kmicromail/libetpan/generic/nntpstorage.c
new file mode 100644
index 0000000..5ba333b
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpstorage.c
@@ -0,0 +1,267 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "nntpstorage.h"
37
38#include <stdlib.h>
39#include <string.h>
40
41#include "maildriver.h"
42#include "nntpdriver.h"
43#include "nntpdriver_cached.h"
44#include "mailstorage_tools.h"
45#include "mail.h"
46
47/* nntp storage */
48
49#define NNTP_DEFAULT_PORT 119
50#define NNTPS_DEFAULT_PORT 563
51
52static int nntp_mailstorage_connect(struct mailstorage * storage);
53static int nntp_mailstorage_get_folder_session(struct mailstorage * storage,
54 char * pathname, mailsession ** result);
55static void nntp_mailstorage_uninitialize(struct mailstorage * storage);
56
57static mailstorage_driver nntp_mailstorage_driver = {
58 .sto_name = "nntp",
59 .sto_connect = nntp_mailstorage_connect,
60 .sto_get_folder_session = nntp_mailstorage_get_folder_session,
61 .sto_uninitialize = nntp_mailstorage_uninitialize,
62};
63
64int nntp_mailstorage_init(struct mailstorage * storage,
65 char * nn_servername, uint16_t nn_port,
66 char * nn_command,
67 int nn_connection_type, int nn_auth_type,
68 char * nn_login, char * nn_password,
69 int nn_cached, char * nn_cache_directory, char * nn_flags_directory)
70{
71 struct nntp_mailstorage * nntp_storage;
72 int res;
73
74 nntp_storage = malloc(sizeof(struct nntp_mailstorage));
75 if (nntp_storage == NULL) {
76 res = MAIL_ERROR_MEMORY;
77 goto err;
78 }
79
80 nntp_storage->nntp_servername = strdup(nn_servername);
81 if (nntp_storage->nntp_servername == NULL) {
82 res = MAIL_ERROR_MEMORY;
83 goto free;
84 }
85
86 nntp_storage->nntp_connection_type = nn_connection_type;
87
88 if (nn_port == 0) {
89 switch (nn_connection_type) {
90 case CONNECTION_TYPE_PLAIN:
91 case CONNECTION_TYPE_COMMAND:
92 nn_port = NNTP_DEFAULT_PORT;
93 break;
94
95 case CONNECTION_TYPE_TLS:
96 case CONNECTION_TYPE_COMMAND_TLS:
97 nn_port = NNTPS_DEFAULT_PORT;
98 break;
99
100 default:
101 res = MAIL_ERROR_INVAL;
102 goto free_servername;
103 }
104 }
105
106 nntp_storage->nntp_port = nn_port;
107
108 if (nn_command != NULL) {
109 nntp_storage->nntp_command = strdup(nn_command);
110 if (nntp_storage->nntp_command == NULL) {
111 res = MAIL_ERROR_MEMORY;
112 goto free_servername;
113 }
114 }
115 else
116 nntp_storage->nntp_command = NULL;
117
118 nntp_storage->nntp_auth_type = nn_auth_type;
119
120 if (nn_login != NULL) {
121 nntp_storage->nntp_login = strdup(nn_login);
122 if (nntp_storage->nntp_login == NULL) {
123 res = MAIL_ERROR_MEMORY;
124 goto free_command;
125 }
126 }
127 else
128 nntp_storage->nntp_login = NULL;
129
130 if (nn_password != NULL) {
131 nntp_storage->nntp_password = strdup(nn_password);
132 if (nntp_storage->nntp_password == NULL) {
133 res = MAIL_ERROR_MEMORY;
134 goto free_login;
135 }
136 }
137 else
138 nntp_storage->nntp_password = NULL;
139
140 nntp_storage->nntp_cached = nn_cached;
141
142 if (nn_cached && (nn_cache_directory != NULL) &&
143 (nn_flags_directory != NULL)) {
144 nntp_storage->nntp_cache_directory = strdup(nn_cache_directory);
145 if (nntp_storage->nntp_cache_directory == NULL) {
146 res = MAIL_ERROR_MEMORY;
147 goto free_password;
148 }
149 nntp_storage->nntp_flags_directory = strdup(nn_flags_directory);
150 if (nntp_storage->nntp_flags_directory == NULL) {
151 res = MAIL_ERROR_MEMORY;
152 goto free_cache_directory;
153 }
154 }
155 else {
156 nntp_storage->nntp_cached = FALSE;
157 nntp_storage->nntp_cache_directory = NULL;
158 nntp_storage->nntp_flags_directory = NULL;
159 }
160
161 storage->sto_data = nntp_storage;
162 storage->sto_driver = &nntp_mailstorage_driver;
163
164 return MAIL_NO_ERROR;
165
166 free_cache_directory:
167 free(nntp_storage->nntp_cache_directory);
168 free_password:
169 free(nntp_storage->nntp_password);
170 free_login:
171 free(nntp_storage->nntp_login);
172 free_command:
173 free(nn_command);
174 free_servername:
175 free(nntp_storage->nntp_servername);
176 free:
177 free(nntp_storage);
178 err:
179 return res;
180}
181
182static void nntp_mailstorage_uninitialize(struct mailstorage * storage)
183{
184 struct nntp_mailstorage * nntp_storage;
185
186 nntp_storage = storage->sto_data;
187
188 if (nntp_storage->nntp_flags_directory != NULL)
189 free(nntp_storage->nntp_flags_directory);
190 if (nntp_storage->nntp_cache_directory != NULL)
191 free(nntp_storage->nntp_cache_directory);
192 if (nntp_storage->nntp_password != NULL)
193 free(nntp_storage->nntp_password);
194 if (nntp_storage->nntp_login != NULL)
195 free(nntp_storage->nntp_login);
196 if (nntp_storage->nntp_command != NULL)
197 free(nntp_storage->nntp_command);
198 free(nntp_storage->nntp_servername);
199 free(nntp_storage);
200
201 storage->sto_data = NULL;
202}
203
204static int nntp_mailstorage_connect(struct mailstorage * storage)
205{
206 struct nntp_mailstorage * nntp_storage;
207 mailsession_driver * driver;
208 int r;
209 int res;
210 mailsession * session;
211
212 nntp_storage = storage->sto_data;
213
214 if (nntp_storage->nntp_cached)
215 driver = nntp_cached_session_driver;
216 else
217 driver = nntp_session_driver;
218
219 r = mailstorage_generic_connect(driver,
220 nntp_storage->nntp_servername,
221 nntp_storage->nntp_port, nntp_storage->nntp_command,
222 nntp_storage->nntp_connection_type,
223 NNTPDRIVER_CACHED_SET_CACHE_DIRECTORY,
224 nntp_storage->nntp_cache_directory,
225 NNTPDRIVER_CACHED_SET_FLAGS_DIRECTORY,
226 nntp_storage->nntp_flags_directory,
227 &session);
228 switch (r) {
229 case MAIL_NO_ERROR_NON_AUTHENTICATED:
230 case MAIL_NO_ERROR_AUTHENTICATED:
231 case MAIL_NO_ERROR:
232 break;
233 default:
234 res = r;
235 goto err;
236 }
237
238 r = mailstorage_generic_auth(session, r,
239 nntp_storage->nntp_connection_type,
240 nntp_storage->nntp_login,
241 nntp_storage->nntp_password);
242 if (r != MAIL_NO_ERROR) {
243 res = r;
244 goto free;
245 }
246
247 storage->sto_session = session;
248
249 return MAIL_NO_ERROR;
250
251 free:
252 mailsession_free(session);
253 err:
254 return res;
255}
256
257static int nntp_mailstorage_get_folder_session(struct mailstorage * storage,
258 char * pathname, mailsession ** result)
259{
260 int r;
261
262 r = mailsession_select_folder(storage->sto_session, pathname);
263
264 * result = storage->sto_session;
265
266 return MAIL_NO_ERROR;
267}
diff --git a/kmicromail/libetpan/generic/nntpstorage.h b/kmicromail/libetpan/generic/nntpstorage.h
new file mode 100644
index 0000000..794c717
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpstorage.h
@@ -0,0 +1,93 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NNTPSTORAGE_H
37
38#define NNTPSTORAGE_H
39
40#include <libetpan/nntpdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46
47/*
48 nntp_mailstorage_init is the constructor for a NNTP storage
49
50 @param storage this is the storage to initialize.
51
52 @param servername this is the name of the NNTP server
53
54 @param port is the port to connect to, on the server.
55 you give 0 to use the default port.
56
57 @param command the command used to connect to the server instead of
58 allowing normal TCP connections to be used.
59
60 @param connection_type is the type of socket layer to use.
61 The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
62 CONNECTION_TYPE_TRY_STARTTLS, CONNECTION_TYPE_TLS,
63 CONNECTION_TYPE_COMMAND, CONNECTION_TYPE_COMMAND_STARTTLS,
64 CONNECTION_TYPE_COMMAND_TRY_STARTTLS, CONNECTION_TYPE_COMMAND_TLS,.
65
66 @param auth_type is the authenticate mechanism to use.
67 The value can be NNTP_AUTH_TYPE_PLAIN.
68
69 @param login is the login of the POP3 account.
70
71 @param password is the password of the POP3 account.
72
73 @param cached if this value is != 0, a persistant cache will be
74 stored on local system.
75
76 @param cache_directory is the location of the cache
77
78 @param flags_directory is the location of the flags
79*/
80
81int nntp_mailstorage_init(struct mailstorage * storage,
82 char * nntp_servername, uint16_t nntp_port,
83 char * nntp_command,
84 int nntp_connection_type, int nntp_auth_type,
85 char * nntp_login, char * nntp_password,
86 int nntp_cached, char * nntp_cache_directory,
87 char * nntp_flags_directory);
88
89#ifdef __cplusplus
90}
91#endif
92
93#endif
diff --git a/kmicromail/libetpan/generic/pop3driver.c b/kmicromail/libetpan/generic/pop3driver.c
new file mode 100644
index 0000000..20b0fc2
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver.c
@@ -0,0 +1,387 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "pop3driver.h"
37
38#include <string.h>
39#include <stdlib.h>
40
41#include "pop3driver_message.h"
42#include "maildriver_tools.h"
43#include "pop3driver_tools.h"
44#include "mailmessage.h"
45
46static int pop3driver_initialize(mailsession * session);
47
48static void pop3driver_uninitialize(mailsession * session);
49
50static int pop3driver_parameters(mailsession * session,
51 int id, void * value);
52
53static int pop3driver_connect_stream(mailsession * session, mailstream * s);
54
55static int pop3driver_starttls(mailsession * session);
56
57static int pop3driver_login(mailsession * session,
58 char * userid, char * password);
59
60static int pop3driver_logout(mailsession * session);
61
62static int pop3driver_noop(mailsession * session);
63
64static int pop3driver_status_folder(mailsession * session, char * mb,
65 uint32_t * result_messages, uint32_t * result_recent,
66 uint32_t * result_unseen);
67
68static int pop3driver_messages_number(mailsession * session, char * mb,
69 uint32_t * result);
70
71static int pop3driver_remove_message(mailsession * session, uint32_t num);
72
73static int pop3driver_get_messages_list(mailsession * session,
74 struct mailmessage_list ** result);
75
76static int pop3driver_get_message(mailsession * session,
77 uint32_t num, mailmessage ** result);
78
79static mailsession_driver local_pop3_session_driver = {
80 .sess_name = "pop3",
81
82 .sess_initialize = pop3driver_initialize,
83 .sess_uninitialize = pop3driver_uninitialize,
84
85 .sess_parameters = pop3driver_parameters,
86
87 .sess_connect_stream = pop3driver_connect_stream,
88 .sess_connect_path = NULL,
89 .sess_starttls = pop3driver_starttls,
90 .sess_login = pop3driver_login,
91 .sess_logout = pop3driver_logout,
92 .sess_noop = pop3driver_noop,
93
94 .sess_build_folder_name = NULL,
95 .sess_create_folder = NULL,
96 .sess_delete_folder = NULL,
97 .sess_rename_folder = NULL,
98 .sess_check_folder = NULL,
99 .sess_examine_folder = NULL,
100 .sess_select_folder = NULL,
101 .sess_expunge_folder = NULL,
102 .sess_status_folder = pop3driver_status_folder,
103 .sess_messages_number = pop3driver_messages_number,
104 .sess_recent_number = pop3driver_messages_number,
105 .sess_unseen_number = pop3driver_messages_number,
106 .sess_list_folders = NULL,
107 .sess_lsub_folders = NULL,
108 .sess_subscribe_folder = NULL,
109 .sess_unsubscribe_folder = NULL,
110
111 .sess_append_message = NULL,
112 .sess_copy_message = NULL,
113 .sess_move_message = NULL,
114
115 .sess_get_messages_list = pop3driver_get_messages_list,
116 .sess_get_envelopes_list = maildriver_generic_get_envelopes_list,
117 .sess_remove_message = pop3driver_remove_message,
118#if 0
119 .sess_search_messages = maildriver_generic_search_messages,
120#endif
121
122 .sess_get_message = pop3driver_get_message,
123 .sess_get_message_by_uid = NULL,
124};
125
126mailsession_driver * pop3_session_driver = &local_pop3_session_driver;
127
128static inline struct pop3_session_state_data *
129get_data(mailsession * session)
130{
131 return session->sess_data;
132}
133
134static mailpop3 * get_pop3_session(mailsession * session)
135{
136 return get_data(session)->pop3_session;
137}
138
139static int pop3driver_initialize(mailsession * session)
140{
141 struct pop3_session_state_data * data;
142 mailpop3 * pop3;
143
144 pop3 = mailpop3_new(0, NULL);
145 if (session == NULL)
146 goto err;
147
148 data = malloc(sizeof(* data));
149 if (data == NULL)
150 goto free;
151
152 data->pop3_session = pop3;
153 data->pop3_auth_type = POP3DRIVER_AUTH_TYPE_PLAIN;
154
155 session->sess_data = data;
156
157 return MAIL_NO_ERROR;
158
159 free:
160 mailpop3_free(pop3);
161 err:
162 return MAIL_ERROR_MEMORY;
163}
164
165static void pop3driver_uninitialize(mailsession * session)
166{
167 struct pop3_session_state_data * data;
168
169 data = get_data(session);
170
171 mailpop3_free(data->pop3_session);
172 free(data);
173
174 session->sess_data = data;
175}
176
177static int pop3driver_connect_stream(mailsession * session, mailstream * s)
178{
179 int r;
180
181 r = mailpop3_connect(get_pop3_session(session), s);
182
183 switch (r) {
184 case MAILPOP3_NO_ERROR:
185 return MAIL_NO_ERROR_NON_AUTHENTICATED;
186
187 default:
188 return pop3driver_pop3_error_to_mail_error(r);
189 }
190}
191
192static int pop3driver_starttls(mailsession * session)
193{
194 int r;
195 int fd;
196 mailstream_low * low;
197 mailstream_low * new_low;
198 mailpop3 * pop3;
199
200 pop3 = get_pop3_session(session);
201
202 r = mailpop3_stls(pop3);
203
204 switch (r) {
205 case MAILPOP3_NO_ERROR:
206 break;
207 default:
208 return pop3driver_pop3_error_to_mail_error(r);
209 }
210
211 low = mailstream_get_low(pop3->pop3_stream);
212 fd = mailstream_low_get_fd(low);
213 if (fd == -1)
214 return MAIL_ERROR_STREAM;
215
216 new_low = mailstream_low_ssl_open(fd);
217 if (new_low == NULL)
218 return MAIL_ERROR_STREAM;
219 mailstream_low_free(low);
220 mailstream_set_low(pop3->pop3_stream, new_low);
221
222 return MAIL_NO_ERROR;
223}
224
225static int pop3driver_parameters(mailsession * session,
226 int id, void * value)
227{
228 struct pop3_session_state_data * data;
229
230 data = get_data(session);
231
232 switch (id) {
233 case POP3DRIVER_SET_AUTH_TYPE:
234 {
235 int * param;
236
237 param = value;
238
239 data->pop3_auth_type = * param;
240 return MAIL_NO_ERROR;
241 }
242 }
243
244 return MAIL_ERROR_INVAL;
245}
246
247static int pop3driver_login(mailsession * session,
248 char * userid, char * password)
249{
250 int r;
251 carray * msg_tab;
252 struct pop3_session_state_data * data;
253
254 data = get_data(session);
255
256 switch (data->pop3_auth_type) {
257 case POP3DRIVER_AUTH_TYPE_TRY_APOP:
258 r = mailpop3_login_apop(get_pop3_session(session), userid, password);
259 if (r != MAILPOP3_NO_ERROR)
260 r = mailpop3_login(get_pop3_session(session), userid, password);
261 break;
262
263 case POP3DRIVER_AUTH_TYPE_APOP:
264 r = mailpop3_login_apop(get_pop3_session(session), userid, password);
265 break;
266
267 default:
268 case POP3DRIVER_AUTH_TYPE_PLAIN:
269 r = mailpop3_login(get_pop3_session(session), userid, password);
270 break;
271 }
272
273 mailpop3_list(get_pop3_session(session), &msg_tab);
274
275 return pop3driver_pop3_error_to_mail_error(r);
276}
277
278static int pop3driver_logout(mailsession * session)
279{
280 int r;
281
282 r = mailpop3_quit(get_pop3_session(session));
283
284 return pop3driver_pop3_error_to_mail_error(r);
285}
286
287static int pop3driver_noop(mailsession * session)
288{
289 int r;
290
291 r = mailpop3_noop(get_pop3_session(session));
292
293 return pop3driver_pop3_error_to_mail_error(r);
294}
295
296static int pop3driver_status_folder(mailsession * session, char * mb,
297 uint32_t * result_messages,
298 uint32_t * result_recent,
299 uint32_t * result_unseen)
300{
301 uint32_t count;
302 int r;
303
304 r = pop3driver_messages_number(session, mb, &count);
305 if (r != MAIL_NO_ERROR)
306 return r;
307
308 * result_messages = count;
309 * result_recent = count;
310 * result_unseen = count;
311
312 return MAIL_NO_ERROR;
313}
314
315static int pop3driver_messages_number(mailsession * session, char * mb,
316 uint32_t * result)
317{
318 carray * msg_tab;
319
320 mailpop3_list(get_pop3_session(session), &msg_tab);
321
322 * result = carray_count(msg_tab) -
323 get_pop3_session(session)->pop3_deleted_count;
324
325 return MAIL_NO_ERROR;
326}
327
328
329/* messages operations */
330
331static int pop3driver_remove_message(mailsession * session, uint32_t num)
332{
333 mailpop3 * pop3;
334 int r;
335
336 pop3 = get_pop3_session(session);
337
338 r = mailpop3_dele(pop3, num);
339 switch (r) {
340 case MAILPOP3_ERROR_BAD_STATE:
341 return MAIL_ERROR_BAD_STATE;
342
343 case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
344 return MAIL_ERROR_MSG_NOT_FOUND;
345
346 case MAILPOP3_ERROR_STREAM:
347 return MAIL_ERROR_STREAM;
348
349 case MAILPOP3_NO_ERROR:
350 return MAIL_NO_ERROR;
351
352 default:
353 return MAIL_ERROR_REMOVE;
354 }
355}
356
357static int pop3driver_get_messages_list(mailsession * session,
358 struct mailmessage_list ** result)
359{
360 mailpop3 * pop3;
361
362 pop3 = get_pop3_session(session);
363
364 return pop3_get_messages_list(pop3, session,
365 pop3_message_driver, result);
366}
367
368static int pop3driver_get_message(mailsession * session,
369 uint32_t num, mailmessage ** result)
370{
371 mailmessage * msg_info;
372 int r;
373
374 msg_info = mailmessage_new();
375 if (msg_info == NULL)
376 return MAIL_ERROR_MEMORY;
377
378 r = mailmessage_init(msg_info, session, pop3_message_driver, num, 0);
379 if (r != MAIL_NO_ERROR) {
380 mailmessage_free(msg_info);
381 return r;
382 }
383
384 * result = msg_info;
385
386 return MAIL_NO_ERROR;
387}
diff --git a/kmicromail/libetpan/generic/pop3driver.h b/kmicromail/libetpan/generic/pop3driver.h
new file mode 100644
index 0000000..2df94db
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef POP3DRIVER_H
37
38#define POP3DRIVER_H
39
40#include <libetpan/pop3driver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * pop3_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/pop3driver_cached.c b/kmicromail/libetpan/generic/pop3driver_cached.c
new file mode 100644
index 0000000..6f97303
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_cached.c
@@ -0,0 +1,857 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "pop3driver_cached.h"
37
38#include "libetpan-config.h"
39
40#include <sys/types.h>
41#include <sys/stat.h>
42#include <fcntl.h>
43#include <string.h>
44#include <unistd.h>
45#include <stdlib.h>
46
47#include "mail.h"
48#include "mail_cache_db.h"
49
50#include "maildriver.h"
51#include "mailmessage.h"
52#include "pop3driver.h"
53#include "mailpop3.h"
54#include "generic_cache.h"
55#include "imfcache.h"
56#include "pop3driver_cached_message.h"
57#include "pop3driver_tools.h"
58#include "maildriver_tools.h"
59
60static int pop3driver_cached_initialize(mailsession * session);
61
62static void pop3driver_cached_uninitialize(mailsession * session);
63
64static int pop3driver_cached_parameters(mailsession * session,
65 int id, void * value);
66
67static int pop3driver_cached_connect_stream(mailsession * session,
68 mailstream * s);
69
70static int pop3driver_cached_starttls(mailsession * session);
71
72static int pop3driver_cached_login(mailsession * session,
73 char * userid, char * password);
74
75static int pop3driver_cached_logout(mailsession * session);
76
77static int pop3driver_cached_check_folder(mailsession * session);
78
79static int pop3driver_cached_noop(mailsession * session);
80
81static int pop3driver_cached_expunge_folder(mailsession * session);
82
83static int pop3driver_cached_status_folder(mailsession * session,
84 char * mb, uint32_t * result_messages, uint32_t * result_recent,
85 uint32_t * result_unseen);
86
87static int pop3driver_cached_messages_number(mailsession * session,
88 char * mb,
89 uint32_t * result);
90
91static int pop3driver_cached_recent_number(mailsession * session,
92 char * mb,
93 uint32_t * result);
94
95static int pop3driver_cached_unseen_number(mailsession * session,
96 char * mb,
97 uint32_t * result);
98
99static int pop3driver_cached_remove_message(mailsession * session,
100 uint32_t num);
101
102static int
103pop3driver_cached_get_messages_list(mailsession * session,
104 struct mailmessage_list ** result);
105
106static int
107pop3driver_cached_get_envelopes_list(mailsession * session,
108 struct mailmessage_list * env_list);
109
110static int pop3driver_cached_get_message(mailsession * session,
111 uint32_t num, mailmessage ** result);
112
113static mailsession_driver local_pop3_cached_session_driver = {
114 .sess_name = "pop3-cached",
115
116 .sess_initialize = pop3driver_cached_initialize,
117 .sess_uninitialize = pop3driver_cached_uninitialize,
118
119 .sess_parameters = pop3driver_cached_parameters,
120
121 .sess_connect_stream = pop3driver_cached_connect_stream,
122 .sess_connect_path = NULL,
123 .sess_starttls = pop3driver_cached_starttls,
124 .sess_login = pop3driver_cached_login,
125 .sess_logout = pop3driver_cached_logout,
126 .sess_noop = pop3driver_cached_noop,
127
128 .sess_build_folder_name = NULL,
129 .sess_create_folder = NULL,
130 .sess_delete_folder = NULL,
131 .sess_rename_folder = NULL,
132 .sess_check_folder = pop3driver_cached_check_folder,
133 .sess_examine_folder = NULL,
134 .sess_select_folder = NULL,
135 .sess_expunge_folder = pop3driver_cached_expunge_folder,
136 .sess_status_folder = pop3driver_cached_status_folder,
137 .sess_messages_number = pop3driver_cached_messages_number,
138 .sess_recent_number = pop3driver_cached_recent_number,
139 .sess_unseen_number = pop3driver_cached_unseen_number,
140 .sess_list_folders = NULL,
141 .sess_lsub_folders = NULL,
142 .sess_subscribe_folder = NULL,
143 .sess_unsubscribe_folder = NULL,
144
145 .sess_append_message = NULL,
146 .sess_copy_message = NULL,
147 .sess_move_message = NULL,
148
149 .sess_get_messages_list = pop3driver_cached_get_messages_list,
150 .sess_get_envelopes_list = pop3driver_cached_get_envelopes_list,
151 .sess_remove_message = pop3driver_cached_remove_message,
152#if 0
153 .sess_search_messages = maildriver_generic_search_messages,
154#endif
155
156 .sess_get_message = pop3driver_cached_get_message,
157 .sess_get_message_by_uid = NULL,
158};
159
160mailsession_driver * pop3_cached_session_driver =
161&local_pop3_cached_session_driver;
162
163#define ENV_NAME "env.db"
164#define FLAGS_NAME "flags.db"
165
166
167static inline struct pop3_cached_session_state_data *
168get_cached_data(mailsession * session)
169{
170 return session->sess_data;
171}
172
173static inline mailsession * get_ancestor(mailsession * session)
174{
175 return get_cached_data(session)->pop3_ancestor;
176}
177
178static inline struct pop3_session_state_data *
179get_ancestor_data(mailsession * session)
180{
181 return get_ancestor(session)->sess_data;
182}
183
184static inline mailpop3 * get_pop3_session(mailsession * session)
185{
186 return get_ancestor_data(session)->pop3_session;
187}
188
189static int pop3driver_cached_initialize(mailsession * session)
190{
191 struct pop3_cached_session_state_data * data;
192
193 data = malloc(sizeof(* data));
194 if (data == NULL)
195 goto err;
196
197 data->pop3_flags_store = mail_flags_store_new();
198 if (data->pop3_flags_store == NULL)
199 goto free_data;
200
201 data->pop3_ancestor = mailsession_new(pop3_session_driver);
202 if (data->pop3_ancestor == NULL)
203 goto free_store;
204
205 data->pop3_flags_hash = chash_new(128, CHASH_COPYNONE);
206 if (data->pop3_flags_hash == NULL)
207 goto free_session;
208
209 session->sess_data = data;
210
211 return MAIL_NO_ERROR;
212
213 free_session:
214 mailsession_free(data->pop3_ancestor);
215 free_store:
216 mail_flags_store_free(data->pop3_flags_store);
217 free_data:
218 free(data);
219 err:
220 return MAIL_ERROR_MEMORY;
221}
222
223static int pop3_flags_store_process(char * flags_directory,
224 struct mail_flags_store * flags_store)
225{
226 char filename_flags[PATH_MAX];
227 struct mail_cache_db * cache_db_flags;
228 MMAPString * mmapstr;
229 unsigned int i;
230 int r;
231 int res;
232
233 if (carray_count(flags_store->fls_tab) == 0)
234 return MAIL_NO_ERROR;
235
236 snprintf(filename_flags, PATH_MAX, "%s/%s",
237 flags_directory, FLAGS_NAME);
238
239 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
240 if (r < 0) {
241 res = MAIL_ERROR_FILE;
242 goto err;
243 }
244
245 mmapstr = mmap_string_new("");
246 if (mmapstr == NULL) {
247 res = MAIL_ERROR_MEMORY;
248 goto close_db_flags;
249 }
250
251 for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
252 mailmessage * msg;
253
254 msg = carray_get(flags_store->fls_tab, i);
255
256 r = pop3driver_write_cached_flags(cache_db_flags, mmapstr,
257 msg->msg_uid, msg->msg_flags);
258 }
259
260 mmap_string_free(mmapstr);
261 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
262
263 mail_flags_store_clear(flags_store);
264
265 return MAIL_NO_ERROR;
266
267 close_db_flags:
268 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
269 err:
270 return res;
271}
272
273static void pop3driver_cached_uninitialize(mailsession * session)
274{
275 struct pop3_cached_session_state_data * data;
276
277 data = get_cached_data(session);
278
279 pop3_flags_store_process(data->pop3_flags_directory,
280 data->pop3_flags_store);
281
282 mail_flags_store_free(data->pop3_flags_store);
283
284 chash_free(data->pop3_flags_hash);
285 mailsession_free(data->pop3_ancestor);
286 free(data);
287
288 session->sess_data = data;
289}
290
291static int pop3driver_cached_check_folder(mailsession * session)
292{
293 struct pop3_cached_session_state_data * pop3_data;
294
295 pop3_data = get_cached_data(session);
296
297 pop3_flags_store_process(pop3_data->pop3_flags_directory,
298 pop3_data->pop3_flags_store);
299
300 return MAIL_NO_ERROR;
301}
302
303static int pop3driver_cached_parameters(mailsession * session,
304 int id, void * value)
305{
306 struct pop3_cached_session_state_data * data;
307 int r;
308
309 data = get_cached_data(session);
310
311 switch (id) {
312 case POP3DRIVER_CACHED_SET_CACHE_DIRECTORY:
313 strncpy(data->pop3_cache_directory, value, PATH_MAX);
314 data->pop3_cache_directory[PATH_MAX - 1] = '\0';
315
316 r = generic_cache_create_dir(data->pop3_cache_directory);
317 if (r != MAIL_NO_ERROR)
318 return r;
319
320 return MAIL_NO_ERROR;
321
322 case POP3DRIVER_CACHED_SET_FLAGS_DIRECTORY:
323 strncpy(data->pop3_flags_directory, value, PATH_MAX);
324 data->pop3_flags_directory[PATH_MAX - 1] = '\0';
325
326 r = generic_cache_create_dir(data->pop3_flags_directory);
327 if (r != MAIL_NO_ERROR)
328 return r;
329
330 return MAIL_NO_ERROR;
331
332 default:
333 return mailsession_parameters(data->pop3_ancestor, id, value);
334 }
335}
336
337static int pop3driver_cached_connect_stream(mailsession * session,
338 mailstream * s)
339{
340 int r;
341
342 r = mailsession_connect_stream(get_ancestor(session), s);
343 if (r != MAIL_NO_ERROR)
344 return r;
345
346 return MAIL_NO_ERROR;
347}
348
349static int pop3driver_cached_starttls(mailsession * session)
350{
351 return mailsession_starttls(get_ancestor(session));
352}
353
354
355static int pop3driver_cached_login(mailsession * session,
356 char * userid, char * password)
357{
358 return mailsession_login(get_ancestor(session), userid, password);
359}
360
361static int pop3driver_cached_logout(mailsession * session)
362{
363 struct pop3_cached_session_state_data * cached_data;
364
365 cached_data = get_cached_data(session);
366
367 pop3_flags_store_process(cached_data->pop3_flags_directory,
368 cached_data->pop3_flags_store);
369
370 return mailsession_logout(get_ancestor(session));
371}
372
373static int pop3driver_cached_noop(mailsession * session)
374{
375 return mailsession_noop(get_ancestor(session));
376}
377
378static int pop3driver_cached_expunge_folder(mailsession * session)
379{
380 int res;
381 struct pop3_cached_session_state_data * cached_data;
382 char filename_flags[PATH_MAX];
383 struct mail_cache_db * cache_db_flags;
384 MMAPString * mmapstr;
385 unsigned int i;
386 int r;
387 carray * msg_tab;
388 mailpop3 * pop3;
389
390 pop3 = get_pop3_session(session);
391
392 cached_data = get_cached_data(session);
393
394 pop3_flags_store_process(cached_data->pop3_flags_directory,
395 cached_data->pop3_flags_store);
396
397 snprintf(filename_flags, PATH_MAX, "%s/%s",
398 cached_data->pop3_flags_directory, FLAGS_NAME);
399
400 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
401 if (r < 0) {
402 res = MAIL_ERROR_MEMORY;
403 goto err;
404 }
405
406 mmapstr = mmap_string_new("");
407 if (mmapstr == NULL) {
408 res = MAIL_ERROR_MEMORY;
409 goto close_db_flags;
410 }
411
412 mailpop3_list(pop3, &msg_tab);
413
414 for(i = 0 ; i < carray_count(msg_tab) ; i++) {
415 struct mailpop3_msg_info * pop3_info;
416 struct mail_flags * flags;
417
418 pop3_info = carray_get(msg_tab, i);
419 if (pop3_info == NULL)
420 continue;
421
422 if (pop3_info->msg_deleted)
423 continue;
424
425 r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
426 session, pop3_info->msg_index, &flags);
427 if (r != MAIL_NO_ERROR)
428 continue;
429
430 if (flags->fl_flags & MAIL_FLAG_DELETED) {
431 r = mailpop3_dele(pop3, pop3_info->msg_index);
432 }
433
434 mail_flags_free(flags);
435 }
436
437 mmap_string_free(mmapstr);
438 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
439
440 return MAIL_NO_ERROR;
441
442 close_db_flags:
443 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
444 err:
445 return res;
446}
447
448static int pop3driver_cached_status_folder(mailsession * session,
449 char * mb, uint32_t * result_messages, uint32_t * result_recent,
450 uint32_t * result_unseen)
451{
452 int res;
453 struct pop3_cached_session_state_data * cached_data;
454 char filename_flags[PATH_MAX];
455 struct mail_cache_db * cache_db_flags;
456 MMAPString * mmapstr;
457 unsigned int i;
458 int r;
459 carray * msg_tab;
460 mailpop3 * pop3;
461 uint32_t recent;
462 uint32_t unseen;
463
464 recent = 0;
465 unseen = 0;
466
467 pop3 = get_pop3_session(session);
468
469 cached_data = get_cached_data(session);
470
471 pop3_flags_store_process(cached_data->pop3_flags_directory,
472 cached_data->pop3_flags_store);
473
474 snprintf(filename_flags, PATH_MAX, "%s/%s",
475 cached_data->pop3_flags_directory, FLAGS_NAME);
476
477 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
478 if (r < 0) {
479 res = MAIL_ERROR_MEMORY;
480 goto err;
481 }
482
483 mmapstr = mmap_string_new("");
484 if (mmapstr == NULL) {
485 res = MAIL_ERROR_MEMORY;
486 goto close_db_flags;
487 }
488
489 mailpop3_list(pop3, &msg_tab);
490
491 for(i = 0 ; i < carray_count(msg_tab) ; i++) {
492 struct mailpop3_msg_info * pop3_info;
493 struct mail_flags * flags;
494
495 pop3_info = carray_get(msg_tab, i);
496 if (pop3_info == NULL)
497 continue;
498
499 if (pop3_info->msg_deleted)
500 continue;
501
502 r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
503 session, pop3_info->msg_index, &flags);
504 if (r != MAIL_NO_ERROR) {
505 recent ++;
506 unseen ++;
507 continue;
508 }
509
510 if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) {
511 recent ++;
512 }
513 if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) {
514 unseen ++;
515 }
516 mail_flags_free(flags);
517
518 }
519
520 mmap_string_free(mmapstr);
521 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
522
523 * result_messages = carray_count(msg_tab) - pop3->pop3_deleted_count;
524 * result_recent = recent;
525 * result_unseen = unseen;
526
527 return MAIL_NO_ERROR;
528
529 close_db_flags:
530 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
531 err:
532 return res;
533}
534
535static int pop3driver_cached_messages_number(mailsession * session,
536 char * mb,
537 uint32_t * result)
538{
539 return mailsession_messages_number(get_ancestor(session), mb, result);
540}
541
542static int pop3driver_cached_recent_number(mailsession * session,
543 char * mb,
544 uint32_t * result)
545{
546 uint32_t messages;
547 uint32_t recent;
548 uint32_t unseen;
549 int r;
550
551 r = pop3driver_cached_status_folder(session, mb,
552 &messages, &recent, &unseen);
553 if (r != MAIL_NO_ERROR)
554 return r;
555
556 * result = recent;
557
558 return MAIL_NO_ERROR;
559}
560
561static int pop3driver_cached_unseen_number(mailsession * session,
562 char * mb,
563 uint32_t * result)
564{
565 uint32_t messages;
566 uint32_t recent;
567 uint32_t unseen;
568 int r;
569
570 r = pop3driver_cached_status_folder(session, mb,
571 &messages, &recent, &unseen);
572 if (r != MAIL_NO_ERROR)
573 return r;
574
575 * result = unseen;
576
577 return MAIL_NO_ERROR;
578}
579
580/* messages operations */
581
582static int pop3driver_cached_remove_message(mailsession * session,
583 uint32_t num)
584{
585 return mailsession_remove_message(get_ancestor(session), num);
586}
587
588static int
589pop3driver_cached_get_messages_list(mailsession * session,
590 struct mailmessage_list ** result)
591{
592 mailpop3 * pop3;
593
594 pop3 = get_pop3_session(session);
595
596 return pop3_get_messages_list(pop3, session,
597 pop3_cached_message_driver, result);
598}
599
600
601static int
602get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
603 mailsession * session, uint32_t num,
604 struct mailimf_fields ** result)
605{
606 int r;
607 char keyname[PATH_MAX];
608 struct mailpop3_msg_info * info;
609 struct mailimf_fields * fields;
610 int res;
611 mailpop3 * pop3;
612
613 pop3 = get_pop3_session(session);
614
615 r = mailpop3_get_msg_info(pop3, num, &info);
616 switch (r) {
617 case MAILPOP3_ERROR_BAD_STATE:
618 return MAIL_ERROR_BAD_STATE;
619 case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
620 return MAIL_ERROR_MSG_NOT_FOUND;
621 case MAILPOP3_NO_ERROR:
622 break;
623 default:
624 return MAIL_ERROR_FETCH;
625 }
626
627 snprintf(keyname, PATH_MAX, "%s-envelope", info->msg_uidl);
628
629 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields);
630 if (r != MAIL_NO_ERROR) {
631 res = r;
632 goto err;
633 }
634
635 * result = fields;
636
637 return MAIL_NO_ERROR;
638
639 err:
640 return res;
641}
642
643static int
644write_cached_envelope(struct mail_cache_db * cache_db,
645 MMAPString * mmapstr,
646 mailsession * session, uint32_t num,
647 struct mailimf_fields * fields)
648{
649 int r;
650 char keyname[PATH_MAX];
651 int res;
652 struct mailpop3_msg_info * info;
653 mailpop3 * pop3;
654
655 pop3 = get_pop3_session(session);
656
657 r = mailpop3_get_msg_info(pop3, num, &info);
658 switch (r) {
659 case MAILPOP3_ERROR_BAD_STATE:
660 return MAIL_ERROR_BAD_STATE;
661 case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
662 return MAIL_ERROR_MSG_NOT_FOUND;
663 case MAILPOP3_NO_ERROR:
664 break;
665 default:
666 return MAIL_ERROR_FETCH;
667 }
668
669 snprintf(keyname, PATH_MAX, "%s-envelope", info->msg_uidl);
670
671 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields);
672 if (r != MAIL_NO_ERROR) {
673 res = r;
674 goto err;
675 }
676
677 return MAIL_NO_ERROR;
678
679 err:
680 return res;
681}
682
683static void get_uid_from_filename(char * filename)
684{
685 char * p;
686
687 p = strstr(filename, "-header");
688 if (p != NULL)
689 * p = 0;
690}
691
692static int
693pop3driver_cached_get_envelopes_list(mailsession * session,
694 struct mailmessage_list * env_list)
695{
696 int r;
697 unsigned int i;
698 struct pop3_cached_session_state_data * cached_data;
699 char filename_env[PATH_MAX];
700 char filename_flags[PATH_MAX];
701 struct mail_cache_db * cache_db_env;
702 struct mail_cache_db * cache_db_flags;
703 MMAPString * mmapstr;
704 int res;
705
706 cached_data = get_cached_data(session);
707
708 pop3_flags_store_process(cached_data->pop3_flags_directory,
709 cached_data->pop3_flags_store);
710
711 snprintf(filename_env, PATH_MAX, "%s/%s",
712 cached_data->pop3_cache_directory, ENV_NAME);
713
714 mmapstr = mmap_string_new("");
715 if (mmapstr == NULL) {
716 res = MAIL_ERROR_MEMORY;
717 goto err;
718 }
719
720 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
721 if (r < 0) {
722 res = MAIL_ERROR_MEMORY;
723 goto free_mmapstr;
724 }
725
726 snprintf(filename_flags, PATH_MAX, "%s/%s",
727 cached_data->pop3_flags_directory, FLAGS_NAME);
728
729 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
730 if (r < 0) {
731 res = MAIL_ERROR_MEMORY;
732 goto close_db_env;
733 }
734
735 /* fill with cached */
736
737 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
738 mailmessage * msg;
739 struct mailimf_fields * fields;
740 struct mail_flags * flags;
741
742 msg = carray_get(env_list->msg_tab, i);
743
744 if (msg->msg_fields == NULL) {
745 r = get_cached_envelope(cache_db_env, mmapstr,
746 session, msg->msg_index, &fields);
747 if (r == MAIL_NO_ERROR) {
748 msg->msg_cached = TRUE;
749 msg->msg_fields = fields;
750 }
751 }
752
753 if (msg->msg_flags == NULL) {
754 r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
755 session, msg->msg_index, &flags);
756 if (r == MAIL_NO_ERROR) {
757 msg->msg_flags = flags;
758 }
759 }
760 }
761
762 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
763 mail_cache_db_close_unlock(filename_env, cache_db_env);
764
765 r = maildriver_generic_get_envelopes_list(session, env_list);
766
767 if (r != MAIL_NO_ERROR) {
768 res = r;
769 goto free_mmapstr;
770 }
771
772 /* add flags */
773
774 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
775 mailmessage * msg;
776
777 msg = carray_get(env_list->msg_tab, i);
778
779 if (msg->msg_flags == NULL)
780 msg->msg_flags = mail_flags_new_empty();
781 }
782
783 r = mail_cache_db_open_lock(filename_env, &cache_db_env);
784 if (r < 0) {
785 res = MAIL_ERROR_MEMORY;
786 goto free_mmapstr;
787 }
788
789 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
790 if (r < 0) {
791 res = MAIL_ERROR_MEMORY;
792 goto close_db_env;
793 }
794
795 /* must write cache */
796
797 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
798 mailmessage * msg;
799
800 msg = carray_get(env_list->msg_tab, i);
801
802 if (msg->msg_fields != NULL) {
803 if (!msg->msg_cached) {
804 r = write_cached_envelope(cache_db_env, mmapstr,
805 session, msg->msg_index, msg->msg_fields);
806 }
807 }
808
809 if (msg->msg_flags != NULL) {
810 r = pop3driver_write_cached_flags(cache_db_flags, mmapstr,
811 msg->msg_uid, msg->msg_flags);
812 }
813 }
814
815 /* flush cache */
816
817 maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list);
818
819 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
820 mail_cache_db_close_unlock(filename_env, cache_db_env);
821 mmap_string_free(mmapstr);
822
823 /* remove cache files */
824
825 maildriver_message_cache_clean_up(cached_data->pop3_cache_directory,
826 env_list, get_uid_from_filename);
827
828 return MAIL_NO_ERROR;
829
830 close_db_env:
831 mail_cache_db_close_unlock(filename_env, cache_db_env);
832 free_mmapstr:
833 mmap_string_free(mmapstr);
834 err:
835 return res;
836}
837
838static int pop3driver_cached_get_message(mailsession * session,
839 uint32_t num, mailmessage ** result)
840{
841 mailmessage * msg_info;
842 int r;
843
844 msg_info = mailmessage_new();
845 if (msg_info == NULL)
846 return MAIL_ERROR_MEMORY;
847
848 r = mailmessage_init(msg_info, session, pop3_cached_message_driver, num, 0);
849 if (r != MAIL_NO_ERROR) {
850 mailmessage_free(msg_info);
851 return r;
852 }
853
854 * result = msg_info;
855
856 return MAIL_NO_ERROR;
857}
diff --git a/kmicromail/libetpan/generic/pop3driver_cached.h b/kmicromail/libetpan/generic/pop3driver_cached.h
new file mode 100644
index 0000000..953e699
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_cached.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef POP3DRIVER_CACHED_H
37
38#define POP3DRIVER_CACHED_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/pop3driver_types.h>
45
46extern mailsession_driver * pop3_cached_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/pop3driver_cached_message.c b/kmicromail/libetpan/generic/pop3driver_cached_message.c
new file mode 100644
index 0000000..7aeb22c
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_cached_message.c
@@ -0,0 +1,355 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "pop3driver_cached_message.h"
37
38#include <string.h>
39#include <stdlib.h>
40
41#include "mail_cache_db.h"
42
43#include "mailmessage.h"
44#include "mailmessage_tools.h"
45#include "pop3driver.h"
46#include "pop3driver_tools.h"
47#include "pop3driver_cached.h"
48#include "pop3driver_message.h"
49#include "generic_cache.h"
50
51static int pop3_prefetch(mailmessage * msg_info);
52
53static void pop3_prefetch_free(struct generic_message_t * msg);
54
55static int pop3_initialize(mailmessage * msg_info);
56
57static void pop3_flush(mailmessage * msg_info);
58
59static void pop3_check(mailmessage * msg_info);
60
61static int pop3_fetch_header(mailmessage * msg_info,
62 char ** result,
63 size_t * result_len);
64
65static int pop3_fetch_size(mailmessage * msg_info,
66 size_t * result);
67
68static int pop3_get_flags(mailmessage * msg_info,
69 struct mail_flags ** result);
70
71static void pop3_uninitialize(mailmessage * msg_info);
72
73static mailmessage_driver local_pop3_cached_message_driver = {
74 .msg_name = "pop3-cached",
75
76 .msg_initialize = pop3_initialize,
77 .msg_uninitialize = pop3_uninitialize,
78
79 .msg_flush = pop3_flush,
80 .msg_check = pop3_check,
81
82 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
83
84 .msg_fetch = mailmessage_generic_fetch,
85 .msg_fetch_header = pop3_fetch_header,
86 .msg_fetch_body = mailmessage_generic_fetch_body,
87 .msg_fetch_size = pop3_fetch_size,
88 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
89 .msg_fetch_section = mailmessage_generic_fetch_section,
90 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
91 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
92 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
93 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
94
95 .msg_get_flags = pop3_get_flags,
96};
97
98mailmessage_driver * pop3_cached_message_driver =
99&local_pop3_cached_message_driver;
100
101
102static inline struct pop3_cached_session_state_data *
103get_cached_session_data(mailmessage * msg)
104{
105 return msg->msg_session->sess_data;
106}
107
108static inline mailsession * get_ancestor_session(mailmessage * msg)
109{
110 return get_cached_session_data(msg)->pop3_ancestor;
111}
112
113static inline struct pop3_session_state_data *
114get_ancestor_session_data(mailmessage * msg)
115{
116 return get_ancestor_session(msg)->sess_data;
117}
118
119static inline mailpop3 * get_pop3_session(mailmessage * msg)
120{
121 return get_ancestor_session_data(msg)->pop3_session;
122}
123
124
125static int pop3_prefetch(mailmessage * msg_info)
126{
127 char * msg_content;
128 size_t msg_length;
129 struct generic_message_t * msg;
130 int r;
131 struct pop3_cached_session_state_data * cached_data;
132 char filename[PATH_MAX];
133
134 /* we try the cached message */
135
136 cached_data = get_cached_session_data(msg_info);
137
138 snprintf(filename, PATH_MAX, "%s/%s",
139 cached_data->pop3_cache_directory, msg_info->msg_uid);
140
141 r = generic_cache_read(filename, &msg_content, &msg_length);
142 if (r == MAIL_NO_ERROR) {
143 msg = msg_info->msg_data;
144
145 msg->msg_message = msg_content;
146 msg->msg_length = msg_length;
147
148 return MAIL_NO_ERROR;
149 }
150
151 /* we get the message through the network */
152
153 r = pop3driver_retr(get_ancestor_session(msg_info), msg_info->msg_index,
154 &msg_content, &msg_length);
155 if (r != MAIL_NO_ERROR)
156 return r;
157
158 /* we write the message cache */
159
160 generic_cache_store(filename, msg_content, msg_length);
161
162 msg = msg_info->msg_data;
163
164 msg->msg_message = msg_content;
165 msg->msg_length = msg_length;
166
167 return MAIL_NO_ERROR;
168}
169
170static void pop3_prefetch_free(struct generic_message_t * msg)
171{
172 if (msg->msg_message != NULL) {
173 mmap_string_unref(msg->msg_message);
174 msg->msg_message = NULL;
175 }
176}
177
178static int pop3_initialize(mailmessage * msg_info)
179{
180 struct generic_message_t * msg;
181 int r;
182 char * uid;
183 struct mailpop3_msg_info * info;
184 mailpop3 * pop3;
185
186 pop3 = get_pop3_session(msg_info);
187
188 r = mailpop3_get_msg_info(pop3, msg_info->msg_index, &info);
189 switch (r) {
190 case MAILPOP3_NO_ERROR:
191 break;
192 default:
193 return pop3driver_pop3_error_to_mail_error(r);
194 }
195
196 uid = strdup(info->msg_uidl);
197 if (uid == NULL)
198 return MAIL_ERROR_MEMORY;
199
200 r = mailmessage_generic_initialize(msg_info);
201 if (r != MAIL_NO_ERROR) {
202 free(uid);
203 return r;
204 }
205
206 msg = msg_info->msg_data;
207 msg->msg_prefetch = pop3_prefetch;
208 msg->msg_prefetch_free = pop3_prefetch_free;
209 msg_info->msg_uid = uid;
210
211 return MAIL_NO_ERROR;
212}
213
214static void pop3_uninitialize(mailmessage * msg_info)
215{
216 mailmessage_generic_uninitialize(msg_info);
217}
218
219#define FLAGS_NAME "flags.db"
220
221static void pop3_flush(mailmessage * msg_info)
222{
223 mailmessage_generic_flush(msg_info);
224}
225
226static void pop3_check(mailmessage * msg_info)
227{
228 int r;
229
230 if (msg_info->msg_flags != NULL) {
231 r = mail_flags_store_set(get_cached_session_data(msg_info)->pop3_flags_store,
232 msg_info);
233 }
234}
235
236
237static int pop3_fetch_header(mailmessage * msg_info,
238 char ** result,
239 size_t * result_len)
240{
241 struct generic_message_t * msg;
242 char * headers;
243 size_t headers_length;
244 int r;
245 struct pop3_cached_session_state_data * cached_data;
246 char filename[PATH_MAX];
247
248 msg = msg_info->msg_data;
249
250 if (msg->msg_message != NULL)
251 return mailmessage_generic_fetch_header(msg_info,
252 result, result_len);
253
254 /* we try the cached message */
255
256 cached_data = get_cached_session_data(msg_info);
257
258 snprintf(filename, PATH_MAX, "%s/%s-header",
259 cached_data->pop3_cache_directory, msg_info->msg_uid);
260
261 r = generic_cache_read(filename, &headers, &headers_length);
262 if (r == MAIL_NO_ERROR) {
263 * result = headers;
264 * result_len = headers_length;
265
266 return MAIL_NO_ERROR;
267 }
268
269 /* we get the message trough the network */
270
271 r = pop3driver_header(get_ancestor_session(msg_info), msg_info->msg_index,
272 &headers, &headers_length);
273 if (r != MAIL_NO_ERROR)
274 return r;
275
276 generic_cache_store(filename, headers, headers_length);
277
278 * result = headers;
279 * result_len = headers_length;
280
281 return MAIL_NO_ERROR;
282}
283
284static int pop3_fetch_size(mailmessage * msg_info,
285 size_t * result)
286{
287 return pop3driver_size(get_ancestor_session(msg_info),
288 msg_info->msg_index, result);
289}
290
291static int pop3_get_flags(mailmessage * msg_info,
292 struct mail_flags ** result)
293{
294 int r;
295 struct mail_flags * flags;
296 struct mail_cache_db * cache_db_flags;
297 char filename_flags[PATH_MAX];
298 int res;
299 struct pop3_cached_session_state_data * cached_data;
300 MMAPString * mmapstr;
301
302 if (msg_info->msg_flags != NULL) {
303 * result = msg_info->msg_flags;
304
305 return MAIL_NO_ERROR;
306 }
307
308 cached_data = get_cached_session_data(msg_info);
309
310 flags = mail_flags_store_get(cached_data->pop3_flags_store,
311 msg_info->msg_index);
312
313 if (flags == NULL) {
314 snprintf(filename_flags, PATH_MAX, "%s/%s",
315 cached_data->pop3_flags_directory, FLAGS_NAME);
316
317 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
318 if (r < 0) {
319 res = MAIL_ERROR_MEMORY;
320 goto err;
321 }
322
323 mmapstr = mmap_string_new("");
324 if (mmapstr == NULL) {
325 res = MAIL_ERROR_MEMORY;
326 goto close_db_flags;
327 }
328
329 r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
330 msg_info->msg_session, msg_info->msg_index, &flags);
331 if (r != MAIL_NO_ERROR) {
332 flags = mail_flags_new_empty();
333 if (flags == NULL) {
334 res = MAIL_ERROR_MEMORY;
335 goto free_mmapstr;
336 }
337 }
338
339 mmap_string_free(mmapstr);
340 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
341 }
342
343 msg_info->msg_flags = flags;
344
345 * result = flags;
346
347 return MAIL_NO_ERROR;
348
349 free_mmapstr:
350 mmap_string_free(mmapstr);
351 close_db_flags:
352 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
353 err:
354 return res;
355}
diff --git a/kmicromail/libetpan/generic/pop3driver_cached_message.h b/kmicromail/libetpan/generic/pop3driver_cached_message.h
new file mode 100644
index 0000000..d03f8e5
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_cached_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef POP3DRIVER_CACHED_MESSAGE_H
37
38#define POP3DRIVER_CACHED_MESSAGE_H
39
40#include <libetpan/pop3driver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * pop3_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/pop3driver_message.c b/kmicromail/libetpan/generic/pop3driver_message.c
new file mode 100644
index 0000000..77bd94c
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_message.c
@@ -0,0 +1,159 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "pop3driver_message.h"
37
38#include "mailmessage_tools.h"
39#include "pop3driver_tools.h"
40#include "pop3driver.h"
41#include "mailpop3.h"
42
43static int pop3_prefetch(mailmessage * msg_info);
44
45static void pop3_prefetch_free(struct generic_message_t * msg);
46
47static int pop3_initialize(mailmessage * msg_info);
48
49static int pop3_fetch_header(mailmessage * msg_info,
50 char ** result,
51 size_t * result_len);
52
53static int pop3_fetch_size(mailmessage * msg_info,
54 size_t * result);
55
56static mailmessage_driver local_pop3_message_driver = {
57 .msg_name = "pop3",
58
59 .msg_initialize = pop3_initialize,
60 .msg_uninitialize = mailmessage_generic_uninitialize,
61
62 .msg_flush = mailmessage_generic_flush,
63 .msg_check = NULL,
64
65 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
66
67 .msg_fetch = mailmessage_generic_fetch,
68 .msg_fetch_header = pop3_fetch_header,
69 .msg_fetch_body = mailmessage_generic_fetch_body,
70 .msg_fetch_size = pop3_fetch_size,
71 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
72 .msg_fetch_section = mailmessage_generic_fetch_section,
73 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
74 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
75 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
76 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
77
78 .msg_get_flags = NULL,
79};
80
81mailmessage_driver * pop3_message_driver = &local_pop3_message_driver;
82
83
84static int pop3_prefetch(mailmessage * msg_info)
85{
86 char * msg_content;
87 size_t msg_length;
88 struct generic_message_t * msg;
89 int r;
90
91 r = pop3driver_retr(msg_info->msg_session, msg_info->msg_index,
92 &msg_content, &msg_length);
93 if (r != MAIL_NO_ERROR)
94 return r;
95
96 msg = msg_info->msg_data;
97
98 msg->msg_message = msg_content;
99 msg->msg_length = msg_length;
100
101 return MAIL_NO_ERROR;
102}
103
104static void pop3_prefetch_free(struct generic_message_t * msg)
105{
106 if (msg->msg_message != NULL) {
107 mmap_string_unref(msg->msg_message);
108 msg->msg_message = NULL;
109 }
110}
111
112static int pop3_initialize(mailmessage * msg_info)
113{
114 struct generic_message_t * msg;
115 int r;
116
117 r = mailmessage_generic_initialize(msg_info);
118 if (r != MAIL_NO_ERROR)
119 return r;
120
121 msg = msg_info->msg_data;
122 msg->msg_prefetch = pop3_prefetch;
123 msg->msg_prefetch_free = pop3_prefetch_free;
124
125 return MAIL_NO_ERROR;
126}
127
128
129static int pop3_fetch_header(mailmessage * msg_info,
130 char ** result,
131 size_t * result_len)
132{
133 struct generic_message_t * msg;
134 char * headers;
135 size_t headers_length;
136 int r;
137
138 msg = msg_info->msg_data;
139
140 if (msg->msg_message != NULL)
141 return mailmessage_generic_fetch_header(msg_info,
142 result, result_len);
143
144 r = pop3driver_header(msg_info->msg_session, msg_info->msg_index,
145 &headers, &headers_length);
146 if (r != MAIL_NO_ERROR)
147 return r;
148
149 * result = headers;
150 * result_len = headers_length;
151
152 return MAIL_NO_ERROR;
153}
154
155static int pop3_fetch_size(mailmessage * msg_info,
156 size_t * result)
157{
158 return pop3driver_size(msg_info->msg_session, msg_info->msg_index, result);
159}
diff --git a/kmicromail/libetpan/generic/pop3driver_message.h b/kmicromail/libetpan/generic/pop3driver_message.h
new file mode 100644
index 0000000..6281a39
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef POP3DRIVER_MESSAGE_H
37
38#define POP3DRIVER_MESSAGE_H
39
40#include <libetpan/pop3driver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * pop3_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/generic/pop3driver_tools.c b/kmicromail/libetpan/generic/pop3driver_tools.c
new file mode 100644
index 0000000..8978b47
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_tools.c
@@ -0,0 +1,344 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "pop3driver_tools.h"
37
38#include <sys/types.h>
39#include <sys/stat.h>
40#include <fcntl.h>
41#include <unistd.h>
42
43#include "maildriver_types.h"
44#include "mailpop3.h"
45#include "pop3driver.h"
46#include "pop3driver_cached.h"
47#include "generic_cache.h"
48#include "imfcache.h"
49#include "mailmessage.h"
50#include "mail_cache_db.h"
51
52int pop3driver_pop3_error_to_mail_error(int error)
53{
54 switch (error) {
55 case MAILPOP3_NO_ERROR:
56 return MAIL_NO_ERROR;
57
58 case MAILPOP3_ERROR_BAD_STATE:
59 return MAIL_ERROR_BAD_STATE;
60
61 case MAILPOP3_ERROR_UNAUTHORIZED:
62 return MAIL_ERROR_CONNECT;
63
64 case MAILPOP3_ERROR_STREAM:
65 return MAIL_ERROR_STREAM;
66
67 case MAILPOP3_ERROR_DENIED:
68 return MAIL_ERROR_CONNECT;
69
70 case MAILPOP3_ERROR_BAD_USER:
71 case MAILPOP3_ERROR_BAD_PASSWORD:
72 return MAIL_ERROR_LOGIN;
73
74 case MAILPOP3_ERROR_CANT_LIST:
75 return MAIL_ERROR_LIST;
76
77 case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
78 return MAIL_ERROR_MSG_NOT_FOUND;
79
80 case MAILPOP3_ERROR_MEMORY:
81 return MAIL_ERROR_MEMORY;
82
83 case MAILPOP3_ERROR_CONNECTION_REFUSED:
84 return MAIL_ERROR_CONNECT;
85
86 case MAILPOP3_ERROR_APOP_NOT_SUPPORTED:
87 return MAIL_ERROR_NO_APOP;
88
89 case MAILPOP3_ERROR_CAPA_NOT_SUPPORTED:
90 return MAIL_ERROR_CAPABILITY;
91
92 case MAILPOP3_ERROR_STLS_NOT_SUPPORTED:
93 return MAIL_ERROR_NO_TLS;
94
95 default:
96 return MAIL_ERROR_INVAL;
97 }
98};
99
100static inline struct pop3_session_state_data *
101session_get_data(mailsession * session)
102{
103 return session->sess_data;
104}
105
106static inline mailpop3 * session_get_pop3_session(mailsession * session)
107{
108 return session_get_data(session)->pop3_session;
109}
110
111static inline struct pop3_cached_session_state_data *
112cached_session_get_data(mailsession * session)
113{
114 return session->sess_data;
115}
116
117static inline mailsession *
118cached_session_get_ancestor(mailsession * session)
119{
120 return cached_session_get_data(session)->pop3_ancestor;
121}
122
123static inline struct pop3_session_state_data *
124cached_session_get_ancestor_data(mailsession * session)
125{
126 return session_get_data(cached_session_get_ancestor(session));
127}
128
129static inline mailpop3 *
130cached_session_get_pop3_session(mailsession * session)
131{
132 return session_get_pop3_session(cached_session_get_ancestor(session));
133}
134
135
136int pop3driver_retr(mailsession * session, uint32_t index,
137 char ** result, size_t * result_len)
138{
139 char * msg_content;
140 size_t msg_length;
141 int r;
142
143 r = mailpop3_retr(session_get_pop3_session(session), index,
144 &msg_content, &msg_length);
145
146 switch (r) {
147 case MAILPOP3_NO_ERROR:
148 break;
149 default:
150 return pop3driver_pop3_error_to_mail_error(r);
151 }
152
153 * result = msg_content;
154 * result_len = msg_length;
155
156 return MAIL_NO_ERROR;
157}
158
159int pop3driver_header(mailsession * session, uint32_t index,
160 char ** result,
161 size_t * result_len)
162{
163 char * headers;
164 size_t headers_length;
165 int r;
166
167 r = mailpop3_header(session_get_pop3_session(session),
168 index, &headers, &headers_length);
169
170 switch (r) {
171 case MAILPOP3_NO_ERROR:
172 break;
173 default:
174 return pop3driver_pop3_error_to_mail_error(r);
175 }
176
177 * result = headers;
178 * result_len = headers_length;
179
180 return MAIL_NO_ERROR;
181}
182
183int pop3driver_size(mailsession * session, uint32_t index,
184 size_t * result)
185{
186 mailpop3 * pop3;
187 carray * msg_tab;
188 struct mailpop3_msg_info * info;
189 int r;
190
191 pop3 = session_get_pop3_session(session);
192
193 mailpop3_list(pop3, &msg_tab);
194
195 r = mailpop3_get_msg_info(pop3, index, &info);
196 switch (r) {
197 case MAILPOP3_NO_ERROR:
198 break;
199 default:
200 return pop3driver_pop3_error_to_mail_error(r);
201 }
202
203 * result = info->msg_size;
204
205 return MAIL_NO_ERROR;
206}
207
208int
209pop3driver_get_cached_flags(struct mail_cache_db * cache_db,
210 MMAPString * mmapstr,
211 mailsession * session,
212 uint32_t num,
213 struct mail_flags ** result)
214{
215 int r;
216 char keyname[PATH_MAX];
217 struct mail_flags * flags;
218 int res;
219 struct mailpop3_msg_info * info;
220
221 r = mailpop3_get_msg_info(cached_session_get_pop3_session(session),
222 num, &info);
223 switch (r) {
224 case MAILPOP3_ERROR_BAD_STATE:
225 return MAIL_ERROR_BAD_STATE;
226 case MAILPOP3_ERROR_NO_SUCH_MESSAGE:
227 return MAIL_ERROR_MSG_NOT_FOUND;
228 case MAILPOP3_NO_ERROR:
229 break;
230 default:
231 return MAIL_ERROR_FETCH;
232 }
233
234 snprintf(keyname, PATH_MAX, "%s-flags", info->msg_uidl);
235
236 r = generic_cache_flags_read(cache_db, mmapstr, keyname, &flags);
237 if (r != MAIL_NO_ERROR) {
238 res = r;
239 goto err;
240 }
241
242 * result = flags;
243
244 return MAIL_NO_ERROR;
245
246 err:
247 return res;
248}
249
250int
251pop3driver_write_cached_flags(struct mail_cache_db * cache_db,
252 MMAPString * mmapstr,
253 char * uid,
254 struct mail_flags * flags)
255{
256 int r;
257 char keyname[PATH_MAX];
258 int res;
259
260 snprintf(keyname, PATH_MAX, "%s-flags", uid);
261
262 r = generic_cache_flags_write(cache_db, mmapstr, keyname, flags);
263 if (r != MAIL_NO_ERROR) {
264 res = r;
265 goto err;
266 }
267
268 return MAIL_NO_ERROR;
269
270 err:
271 return res;
272}
273
274int pop3_get_messages_list(mailpop3 * pop3,
275 mailsession * session,
276 mailmessage_driver * driver,
277 struct mailmessage_list ** result)
278{
279 carray * msg_tab;
280 carray * tab;
281 struct mailmessage_list * env_list;
282 unsigned int i;
283 int res;
284 int r;
285
286 mailpop3_list(pop3, &msg_tab);
287
288 tab = carray_new(128);
289 if (tab == NULL) {
290 res = MAIL_ERROR_MEMORY;
291 goto err;
292 }
293
294 for(i = 0 ; i < carray_count(msg_tab) ; i++) {
295 struct mailpop3_msg_info * pop3_info;
296 mailmessage * msg;
297
298 pop3_info = carray_get(msg_tab, i);
299
300 if (pop3_info == NULL)
301 continue;
302
303 if (pop3_info->msg_deleted)
304 continue;
305
306 msg = mailmessage_new();
307 if (msg == NULL) {
308 res = MAIL_ERROR_MEMORY;
309 goto free_list;
310 }
311
312 r = mailmessage_init(msg, session, driver,
313 (uint32_t) pop3_info->msg_index, pop3_info->msg_size);
314 if (r != MAIL_NO_ERROR) {
315 mailmessage_free(msg);
316 res = r;
317 goto free_list;
318 }
319
320 r = carray_add(tab, msg, NULL);
321 if (r < 0) {
322 mailmessage_free(msg);
323 res = MAIL_ERROR_MEMORY;
324 goto free_list;
325 }
326 }
327
328 env_list = mailmessage_list_new(/*list*/ tab);
329 if (env_list == NULL) {
330 res = MAIL_ERROR_MEMORY;
331 goto free_list;
332 }
333
334 * result = env_list;
335
336 return MAIL_NO_ERROR;
337
338 free_list:
339 for(i = 0 ; i < carray_count(tab) ; i ++)
340 mailmessage_free(carray_get(tab, i));
341 carray_free(tab);
342 err:
343 return res;
344}
diff --git a/kmicromail/libetpan/generic/pop3driver_tools.h b/kmicromail/libetpan/generic/pop3driver_tools.h
new file mode 100644
index 0000000..ad5f589
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_tools.h
@@ -0,0 +1,82 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef POP3DRIVER_TOOLS_H
37
38#define POP3DRIVER_TOOLS_H
39
40#include "mail_cache_db_types.h"
41#include "pop3driver_types.h"
42#include "mailpop3.h"
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48int pop3driver_pop3_error_to_mail_error(int error);
49
50int pop3driver_retr(mailsession * session, uint32_t index,
51 char ** result, size_t * result_len);
52
53int pop3driver_header(mailsession * session, uint32_t index,
54 char ** result,
55 size_t * result_len);
56
57int pop3driver_size(mailsession * session, uint32_t index,
58 size_t * result);
59
60int
61pop3driver_get_cached_flags(struct mail_cache_db * cache_db,
62 MMAPString * mmapstr,
63 mailsession * session,
64 uint32_t num,
65 struct mail_flags ** result);
66
67int
68pop3driver_write_cached_flags(struct mail_cache_db * cache_db,
69 MMAPString * mmapstr,
70 char * uid,
71 struct mail_flags * flags);
72
73int pop3_get_messages_list(mailpop3 * pop3,
74 mailsession * session,
75 mailmessage_driver * driver,
76 struct mailmessage_list ** result);
77
78#ifdef __cplusplus
79}
80#endif
81
82#endif
diff --git a/kmicromail/libetpan/generic/pop3driver_types.h b/kmicromail/libetpan/generic/pop3driver_types.h
new file mode 100644
index 0000000..73286d8
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3driver_types.h
@@ -0,0 +1,153 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef POP3DRIVER_TYPES_H
37
38#define POP3DRIVER_TYPES_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/maildriver_types.h>
43#include <libetpan/mailpop3.h>
44#include <libetpan/maildriver_types.h>
45#include <libetpan/chash.h>
46#include <libetpan/mailstorage_types.h>
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52/* POP3 driver for session */
53
54enum {
55 POP3DRIVER_SET_AUTH_TYPE = 1,
56};
57
58enum {
59 POP3DRIVER_AUTH_TYPE_PLAIN = 0,
60 POP3DRIVER_AUTH_TYPE_APOP,
61 POP3DRIVER_AUTH_TYPE_TRY_APOP,
62};
63
64struct pop3_session_state_data {
65 int pop3_auth_type;
66 mailpop3 * pop3_session;
67};
68
69/* cached POP3 driver for session */
70
71enum {
72 /* the mapping of the parameters should be the same as for pop3 */
73 POP3DRIVER_CACHED_SET_AUTH_TYPE = 1,
74 /* cache specific */
75 POP3DRIVER_CACHED_SET_CACHE_DIRECTORY,
76 POP3DRIVER_CACHED_SET_FLAGS_DIRECTORY,
77};
78
79struct pop3_cached_session_state_data {
80 mailsession * pop3_ancestor;
81 char pop3_cache_directory[PATH_MAX];
82 char pop3_flags_directory[PATH_MAX];
83 chash * pop3_flags_hash;
84 carray * pop3_flags_array;
85 struct mail_flags_store * pop3_flags_store;
86};
87
88/* pop3 storage */
89
90/*
91 pop3_mailstorage is the state data specific to the POP3 storage.
92
93 - servername this is the name of the POP3 server
94
95 - port is the port to connect to, on the server.
96 you give 0 to use the default port.
97
98 - connection_type is the type of socket layer to use.
99 The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
100 CONNECTION_TYPE_TRY_STARTTLS or CONNECTION_TYPE_TLS.
101
102 - auth_type is the authenticate mechanism to use.
103 The value can be POP3_AUTH_TYPE_PLAIN, POP3_AUTH_TYPE_APOP
104 or POP3_AUTH_TYPE_TRY_APOP. Other values are not yet implemented.
105
106 - login is the login of the POP3 account.
107
108 - password is the password of the POP3 account.
109
110 - cached if this value is != 0, a persistant cache will be
111 stored on local system.
112
113 - cache_directory is the location of the cache.
114
115 - flags_directory is the location of the flags.
116*/
117
118struct pop3_mailstorage {
119 char * pop3_servername;
120 uint16_t pop3_port;
121 char * pop3_command;
122 int pop3_connection_type;
123
124 int pop3_auth_type;
125 char * pop3_login;
126 char * pop3_password;
127
128 int pop3_cached;
129 char * pop3_cache_directory;
130 char * pop3_flags_directory;
131};
132
133/* this is the type of POP3 authentication */
134
135enum {
136 POP3_AUTH_TYPE_PLAIN, /* plain text authentication */
137 POP3_AUTH_TYPE_APOP, /* APOP authentication */
138 POP3_AUTH_TYPE_TRY_APOP, /* first, try APOP, if it fails,
139 try plain text */
140 POP3_AUTH_TYPE_SASL_ANONYMOUS, /* SASL anonymous */
141 POP3_AUTH_TYPE_SASL_CRAM_MD5, /* SASL CRAM MD5 */
142 POP3_AUTH_TYPE_SASL_KERBEROS_V4, /* SASL KERBEROS V4 */
143 POP3_AUTH_TYPE_SASL_PLAIN, /* SASL plain */
144 POP3_AUTH_TYPE_SASL_SCRAM_MD5, /* SASL SCRAM MD5 */
145 POP3_AUTH_TYPE_SASL_GSSAPI, /* SASL GSSAPI */
146 POP3_AUTH_TYPE_SASL_DIGEST_MD5, /* SASL digest MD5 */
147};
148
149#ifdef __cplusplus
150}
151#endif
152
153#endif
diff --git a/kmicromail/libetpan/generic/pop3storage.c b/kmicromail/libetpan/generic/pop3storage.c
new file mode 100644
index 0000000..8e7a94e
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3storage.c
@@ -0,0 +1,284 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "pop3storage.h"
37
38#include <stdlib.h>
39#include <string.h>
40
41#include "mail.h"
42#include "mailstorage_tools.h"
43#include "maildriver.h"
44
45/* pop3 storage */
46
47#define POP3_DEFAULT_PORT 110
48#define POP3S_DEFAULT_PORT 995
49
50static int pop3_mailstorage_connect(struct mailstorage * storage);
51static int pop3_mailstorage_get_folder_session(struct mailstorage * storage,
52 char * pathname, mailsession ** result);
53static void pop3_mailstorage_uninitialize(struct mailstorage * storage);
54
55static mailstorage_driver pop3_mailstorage_driver = {
56 .sto_name = "pop3",
57 .sto_connect = pop3_mailstorage_connect,
58 .sto_get_folder_session = pop3_mailstorage_get_folder_session,
59 .sto_uninitialize = pop3_mailstorage_uninitialize,
60};
61
62int pop3_mailstorage_init(struct mailstorage * storage,
63 char * pop3_servername, uint16_t pop3_port,
64 char * pop3_command,
65 int pop3_connection_type, int pop3_auth_type,
66 char * pop3_login, char * pop3_password,
67 int pop3_cached, char * pop3_cache_directory, char * pop3_flags_directory)
68{
69 struct pop3_mailstorage * pop3_storage;
70
71 pop3_storage = malloc(sizeof(struct pop3_mailstorage));
72 if (pop3_storage == NULL)
73 goto err;
74
75 pop3_storage->pop3_servername = strdup(pop3_servername);
76 if (pop3_storage->pop3_servername == NULL)
77 goto free;
78
79 pop3_storage->pop3_connection_type = pop3_connection_type;
80
81 if (pop3_port == 0) {
82 switch (pop3_connection_type) {
83 case CONNECTION_TYPE_PLAIN:
84 case CONNECTION_TYPE_TRY_STARTTLS:
85 case CONNECTION_TYPE_STARTTLS:
86 case CONNECTION_TYPE_COMMAND:
87 case CONNECTION_TYPE_COMMAND_TRY_STARTTLS:
88 case CONNECTION_TYPE_COMMAND_STARTTLS:
89 pop3_port = POP3_DEFAULT_PORT;
90 break;
91
92 case CONNECTION_TYPE_TLS:
93 case CONNECTION_TYPE_COMMAND_TLS:
94 pop3_port = POP3S_DEFAULT_PORT;
95 break;
96 }
97 }
98
99 pop3_storage->pop3_port = pop3_port;
100
101 if (pop3_command != NULL) {
102 pop3_storage->pop3_command = strdup(pop3_command);
103 if (pop3_storage->pop3_command == NULL)
104 goto free_servername;
105 }
106 else
107 pop3_storage->pop3_command = NULL;
108
109 pop3_storage->pop3_auth_type = pop3_auth_type;
110
111 if (pop3_login != NULL) {
112 pop3_storage->pop3_login = strdup(pop3_login);
113 if (pop3_storage->pop3_login == NULL)
114 goto free_command;
115 }
116 else
117 pop3_storage->pop3_login = NULL;
118
119 if (pop3_password != NULL) {
120 pop3_storage->pop3_password = strdup(pop3_password);
121 if (pop3_storage->pop3_password == NULL)
122 goto free_login;
123 }
124 else
125 pop3_storage->pop3_password = NULL;
126
127 pop3_storage->pop3_cached = pop3_cached;
128
129 if (pop3_cached && (pop3_cache_directory != NULL) &&
130 (pop3_flags_directory != NULL)) {
131 pop3_storage->pop3_cache_directory = strdup(pop3_cache_directory);
132 if (pop3_storage->pop3_cache_directory == NULL)
133 goto free_password;
134 pop3_storage->pop3_flags_directory = strdup(pop3_flags_directory);
135 if (pop3_storage->pop3_flags_directory == NULL)
136 goto free_cache_directory;
137 }
138 else {
139 pop3_storage->pop3_cached = FALSE;
140 pop3_storage->pop3_cache_directory = NULL;
141 pop3_storage->pop3_flags_directory = NULL;
142 }
143
144 storage->sto_data = pop3_storage;
145 storage->sto_driver = &pop3_mailstorage_driver;
146
147 return MAIL_NO_ERROR;
148
149 free_cache_directory:
150 free(pop3_storage->pop3_cache_directory);
151 free_password:
152 if (pop3_storage->pop3_password != NULL)
153 free(pop3_storage->pop3_password);
154 free_login:
155 if (pop3_storage->pop3_login != NULL)
156 free(pop3_storage->pop3_login);
157 free_command:
158 if (pop3_storage->pop3_command != NULL)
159 free(pop3_storage->pop3_command);
160 free_servername:
161 if (pop3_storage->pop3_servername != NULL)
162 free(pop3_storage->pop3_servername);
163 free:
164 free(pop3_storage);
165 err:
166 return MAIL_ERROR_MEMORY;
167}
168
169static void pop3_mailstorage_uninitialize(struct mailstorage * storage)
170{
171 struct pop3_mailstorage * pop3_storage;
172
173 pop3_storage = storage->sto_data;
174
175 if (pop3_storage->pop3_flags_directory != NULL)
176 free(pop3_storage->pop3_flags_directory);
177 if (pop3_storage->pop3_cache_directory != NULL)
178 free(pop3_storage->pop3_cache_directory);
179 if (pop3_storage->pop3_password != NULL)
180 free(pop3_storage->pop3_password);
181 if (pop3_storage->pop3_login != NULL)
182 free(pop3_storage->pop3_login);
183 if (pop3_storage->pop3_command != NULL)
184 free(pop3_storage->pop3_command);
185 free(pop3_storage->pop3_servername);
186 free(pop3_storage);
187
188 storage->sto_data = pop3_storage;
189}
190
191static int pop3_mailstorage_connect(struct mailstorage * storage)
192{
193 struct pop3_mailstorage * pop3_storage;
194 mailsession_driver * driver;
195 int r;
196 int res;
197 mailsession * session;
198 int auth_type;
199
200 pop3_storage = storage->sto_data;
201
202 if (pop3_storage->pop3_cached)
203 driver = pop3_cached_session_driver;
204 else
205 driver = pop3_session_driver;
206
207 r = mailstorage_generic_connect(driver,
208 pop3_storage->pop3_servername,
209 pop3_storage->pop3_port, pop3_storage->pop3_command,
210 pop3_storage->pop3_connection_type,
211 POP3DRIVER_CACHED_SET_CACHE_DIRECTORY,
212 pop3_storage->pop3_cache_directory,
213 POP3DRIVER_CACHED_SET_FLAGS_DIRECTORY,
214 pop3_storage->pop3_flags_directory,
215 &session);
216 switch (r) {
217 case MAIL_NO_ERROR_NON_AUTHENTICATED:
218 case MAIL_NO_ERROR_AUTHENTICATED:
219 case MAIL_NO_ERROR:
220 break;
221 default:
222 res = r;
223 goto err;
224 }
225
226 auth_type = -1;
227 switch (pop3_storage->pop3_auth_type) {
228 case POP3_AUTH_TYPE_PLAIN:
229 auth_type = POP3DRIVER_AUTH_TYPE_PLAIN;
230 break;
231 case POP3_AUTH_TYPE_APOP:
232 auth_type = POP3DRIVER_AUTH_TYPE_APOP;
233 break;
234 case POP3_AUTH_TYPE_TRY_APOP:
235 auth_type = POP3DRIVER_AUTH_TYPE_TRY_APOP;
236 break;
237 }
238
239 if (auth_type != -1) {
240 mailsession_parameters(session, POP3DRIVER_SET_AUTH_TYPE, &auth_type);
241 }
242
243 r = mailstorage_generic_auth(session, r,
244 pop3_storage->pop3_auth_type,
245 pop3_storage->pop3_login,
246 pop3_storage->pop3_password);
247 if (r != MAIL_NO_ERROR) {
248 if (pop3_storage->pop3_auth_type == POP3_AUTH_TYPE_TRY_APOP) {
249 /* try in clear authentication */
250 mailsession_free(session);
251
252 pop3_storage->pop3_auth_type = POP3_AUTH_TYPE_PLAIN;
253 r = mailstorage_connect(storage);
254 if (r != MAIL_NO_ERROR) {
255 res = r;
256 return res;
257 }
258 pop3_storage->pop3_auth_type = POP3_AUTH_TYPE_TRY_APOP;
259
260 return MAIL_NO_ERROR;
261 }
262
263 res = r;
264 goto free;
265 }
266
267 storage->sto_session = session;
268
269 return MAIL_NO_ERROR;
270
271 free:
272 mailsession_free(session);
273 err:
274 return res;
275}
276
277static int pop3_mailstorage_get_folder_session(struct mailstorage * storage,
278 char * pathname, mailsession ** result)
279{
280 * result = storage->sto_session;
281
282 return MAIL_NO_ERROR;
283}
284
diff --git a/kmicromail/libetpan/generic/pop3storage.h b/kmicromail/libetpan/generic/pop3storage.h
new file mode 100644
index 0000000..c2118b6
--- a/dev/null
+++ b/kmicromail/libetpan/generic/pop3storage.h
@@ -0,0 +1,95 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef POP3STORAGE_H
37
38#define POP3STORAGE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/pop3driver_types.h>
45#include <libetpan/pop3driver.h>
46#include <libetpan/pop3driver_cached.h>
47
48/*
49 pop3_mailstorage_init is the constructor for a POP3 storage
50
51 @param storage this is the storage to initialize.
52
53 @param servername this is the name of the POP3 server
54
55 @param port is the port to connect to, on the server.
56 you give 0 to use the default port.
57
58 @param command the command used to connect to the server instead of
59 allowing normal TCP connections to be used.
60
61 @param connection_type is the type of socket layer to use.
62 The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
63 CONNECTION_TYPE_TRY_STARTTLS, CONNECTION_TYPE_TLS,
64 CONNECTION_TYPE_COMMAND, CONNECTION_TYPE_COMMAND_STARTTLS,
65 CONNECTION_TYPE_COMMAND_TRY_STARTTLS, CONNECTION_TYPE_COMMAND_TLS,.
66
67 @param auth_type is the authenticate mechanism to use.
68 The value can be POP3_AUTH_TYPE_PLAIN, POP3_AUTH_TYPE_APOP
69 or POP3_AUTH_TYPE_TRY_APOP. Other values are not yet implemented.
70
71 @param login is the login of the POP3 account.
72
73 @param password is the password of the POP3 account.
74
75 @param cached if this value is != 0, a persistant cache will be
76 stored on local system.
77
78 @param cache_directory is the location of the cache
79
80 @param flags_directory is the location of the flags
81*/
82
83int pop3_mailstorage_init(struct mailstorage * storage,
84 char * pop3_servername, uint16_t pop3_port,
85 char * pop3_command,
86 int pop3_connection_type, int pop3_auth_type,
87 char * pop3_login, char * pop3_password,
88 int pop3_cached, char * pop3_cache_directory,
89 char * pop3_flags_directory);
90
91#ifdef __cplusplus
92}
93#endif
94
95#endif
diff --git a/kmicromail/libetpan/imap/.libs/libmailimap.a b/kmicromail/libetpan/imap/.libs/libmailimap.a
new file mode 100644
index 0000000..c98f6a7
--- a/dev/null
+++ b/kmicromail/libetpan/imap/.libs/libmailimap.a
Binary files differ
diff --git a/kmicromail/libetpan/imap/TODO b/kmicromail/libetpan/imap/TODO
new file mode 100644
index 0000000..a787a3b
--- a/dev/null
+++ b/kmicromail/libetpan/imap/TODO
@@ -0,0 +1,4 @@
1- literal data send progress
2- implement draft-16 (rfc 2822 things)
3- more efficient parser
4
diff --git a/kmicromail/libetpan/imap/mailimap.c b/kmicromail/libetpan/imap/mailimap.c
new file mode 100644
index 0000000..c8fbfee
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap.c
@@ -0,0 +1,2161 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimap.h"
37#include "mailimap_parser.h"
38#include "mailimap_sender.h"
39#include "mail.h"
40
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44
45#ifdef DEBUG
46#include "mailimap_print.h"
47#endif
48
49/*
50 RFC 2060 : IMAP4rev1
51 draft-crispin-imapv-15
52 RFC 2222 : Simple Authentication and Security Layer
53
542061 IMAP4 Compatibility with IMAP2bis. M. Crispin. December 1996.
55 (Format: TXT=5867 bytes) (Obsoletes RFC1730) (Status: INFORMATIONAL)
56
572062 Internet Message Access Protocol - Obsolete Syntax. M. Crispin.
58 December 1996. (Format: TXT=14222 bytes) (Status: INFORMATIONAL)
59
602086 IMAP4 ACL extension. J. Myers. January 1997. (Format: TXT=13925
61 bytes) (Status: PROPOSED STANDARD)
62
632087 IMAP4 QUOTA extension. J. Myers. January 1997. (Format: TXT=8542
64 bytes) (Status: PROPOSED STANDARD)
65
662088 IMAP4 non-synchronizing literals. J. Myers. January 1997.
67 (Format: TXT=4052 bytes) (Status: PROPOSED STANDARD)
68
692177 IMAP4 IDLE command. B. Leiba. June 1997. (Format: TXT=6770 bytes)
70 (Status: PROPOSED STANDARD)
71
722180 IMAP4 Multi-Accessed Mailbox Practice. M. Gahrns. July 1997.
73 (Format: TXT=24750 bytes) (Status: INFORMATIONAL)
74
752192 IMAP URL Scheme. C. Newman. September 1997. (Format: TXT=31426
76 bytes) (Status: PROPOSED STANDARD)
77
782193 IMAP4 Mailbox Referrals. M. Gahrns. September 1997. (Format:
79 TXT=16248 bytes) (Status: PROPOSED STANDARD)
80
812195 IMAP/POP AUTHorize Extension for Simple Challenge/Response. J.
82 Klensin, R. Catoe, P. Krumviede. September 1997. (Format: TXT=10468
83 bytes) (Obsoletes RFC2095) (Status: PROPOSED STANDARD)
84
852221 IMAP4 Login Referrals. M. Gahrns. October 1997. (Format: TXT=9251
86 bytes) (Status: PROPOSED STANDARD)
87
882342 IMAP4 Namespace. M. Gahrns, C. Newman. May 1998. (Format:
89 TXT=19489 bytes) (Status: PROPOSED STANDARD)
90
912359 IMAP4 UIDPLUS extension. J. Myers. June 1998. (Format: TXT=10862
92 bytes) (Status: PROPOSED STANDARD)
93
942595 Using TLS with IMAP, POP3 and ACAP. C. Newman. June 1999.
95 (Format: TXT=32440 bytes) (Status: PROPOSED STANDARD)
96
972683 IMAP4 Implementation Recommendations. B. Leiba. September 1999.
98 (Format: TXT=56300 bytes) (Status: INFORMATIONAL)
99
1002971 IMAP4 ID extension. T. Showalter. October 2000. (Format:
101 TXT=14670 bytes) (Status: PROPOSED STANDARD)
102
103http://www.ietf.org/ids.by.wg/imapext.html
104*/
105
106static char * read_line(mailimap * session);
107
108static int send_current_tag(mailimap * session);
109
110static int parse_response(mailimap * session,
111 struct mailimap_response ** result);
112
113static int parse_greeting(mailimap * session,
114 struct mailimap_greeting ** result);
115
116
117/* struct mailimap_response_info * */
118
119static void resp_text_store(mailimap * session,
120 struct mailimap_resp_text *
121 resp_text)
122{
123 struct mailimap_resp_text_code * resp_text_code;
124
125 resp_text_code = resp_text->rsp_code;
126
127 if (resp_text_code != NULL) {
128 switch (resp_text_code->rc_type) {
129 case MAILIMAP_RESP_TEXT_CODE_ALERT:
130 if (session->imap_response_info)
131 if (session->imap_response_info->rsp_alert != NULL)
132 free(session->imap_response_info->rsp_alert);
133 session->imap_response_info->rsp_alert = strdup(resp_text->rsp_text);
134 break;
135
136 case MAILIMAP_RESP_TEXT_CODE_BADCHARSET:
137 if (session->imap_response_info) {
138 if (session->imap_response_info->rsp_badcharset != NULL) {
139 clist_foreach(resp_text_code->rc_data.rc_badcharset,
140 (clist_func) mailimap_astring_free, NULL);
141 clist_free(resp_text_code->rc_data.rc_badcharset);
142 }
143 session->imap_response_info->rsp_badcharset =
144 resp_text_code->rc_data.rc_badcharset;
145 resp_text_code->rc_data.rc_badcharset = NULL;
146 }
147 break;
148
149 case MAILIMAP_RESP_TEXT_CODE_CAPABILITY_DATA:
150 if (session->imap_connection_info) {
151 if (session->imap_connection_info->imap_capability != NULL)
152 mailimap_capability_data_free(session->imap_connection_info->imap_capability);
153 session->imap_connection_info->imap_capability =
154 resp_text_code->rc_data.rc_cap_data;
155 /* detach before free */
156 resp_text_code->rc_data.rc_cap_data = NULL;
157 }
158 break;
159
160 case MAILIMAP_RESP_TEXT_CODE_PARSE:
161 if (session->imap_response_info) {
162 if (session->imap_response_info->rsp_parse != NULL)
163 free(session->imap_response_info->rsp_parse);
164 session->imap_response_info->rsp_parse = strdup(resp_text->rsp_text);
165 }
166 break;
167
168 case MAILIMAP_RESP_TEXT_CODE_PERMANENTFLAGS:
169 if (session->imap_selection_info) {
170 if (session->imap_selection_info->sel_perm_flags != NULL) {
171 clist_foreach(session->imap_selection_info->sel_perm_flags,
172 (clist_func) mailimap_flag_perm_free, NULL);
173 clist_free(session->imap_selection_info->sel_perm_flags);
174 }
175 session->imap_selection_info->sel_perm_flags =
176 resp_text_code->rc_data.rc_perm_flags;
177 /* detach before free */
178 resp_text_code->rc_data.rc_perm_flags = NULL;
179 }
180 break;
181
182 case MAILIMAP_RESP_TEXT_CODE_READ_ONLY:
183 if (session->imap_selection_info)
184 session->imap_selection_info->sel_perm = MAILIMAP_MAILBOX_READONLY;
185 break;
186
187 case MAILIMAP_RESP_TEXT_CODE_READ_WRITE:
188 if (session->imap_selection_info)
189 session->imap_selection_info->sel_perm = MAILIMAP_MAILBOX_READWRITE;
190 break;
191
192 case MAILIMAP_RESP_TEXT_CODE_TRY_CREATE:
193 if (session->imap_response_info)
194 session->imap_response_info->rsp_trycreate = TRUE;
195 break;
196
197 case MAILIMAP_RESP_TEXT_CODE_UIDNEXT:
198 if (session->imap_selection_info)
199 session->imap_selection_info->sel_uidnext =
200 resp_text_code->rc_data.rc_uidnext;
201 break;
202
203 case MAILIMAP_RESP_TEXT_CODE_UIDVALIDITY:
204 if (session->imap_selection_info)
205 session->imap_selection_info->sel_uidvalidity =
206 resp_text_code->rc_data.rc_uidvalidity;
207 break;
208
209 case MAILIMAP_RESP_TEXT_CODE_UNSEEN:
210 if (session->imap_selection_info)
211 session->imap_selection_info->sel_first_unseen =
212 resp_text_code->rc_data.rc_first_unseen;
213 break;
214 }
215 }
216}
217
218static void resp_cond_state_store(mailimap * session,
219 struct mailimap_resp_cond_state * resp_cond_state)
220{
221 resp_text_store(session, resp_cond_state->rsp_text);
222}
223
224static void mailbox_data_store(mailimap * session,
225 struct mailimap_mailbox_data * mb_data)
226{
227 int r;
228
229 switch (mb_data->mbd_type) {
230 case MAILIMAP_MAILBOX_DATA_FLAGS:
231 if (session->imap_selection_info) {
232 if (session->imap_selection_info->sel_flags != NULL)
233 mailimap_flag_list_free(session->imap_selection_info->sel_flags);
234 session->imap_selection_info->sel_flags = mb_data->mbd_data.mbd_flags;
235 mb_data->mbd_data.mbd_flags = NULL;
236 }
237 break;
238
239 case MAILIMAP_MAILBOX_DATA_LIST:
240 if (session->imap_response_info) {
241 r = clist_append(session->imap_response_info->rsp_mailbox_list,
242 mb_data->mbd_data.mbd_list);
243 if (r == 0)
244 mb_data->mbd_data.mbd_list = NULL;
245 else {
246 /* TODO must handle error case */
247 }
248 }
249 break;
250
251 case MAILIMAP_MAILBOX_DATA_LSUB:
252 if (session->imap_response_info) {
253 r = clist_append(session->imap_response_info->rsp_mailbox_lsub,
254 mb_data->mbd_data.mbd_lsub);
255 if (r == 0)
256 mb_data->mbd_data.mbd_lsub = NULL;
257 else {
258 /* TODO must handle error case */
259 }
260 }
261 break;
262
263 case MAILIMAP_MAILBOX_DATA_SEARCH:
264 if (session->imap_response_info) {
265 if (session->imap_response_info->rsp_search_result != NULL) {
266 if (mb_data->mbd_data.mbd_search != NULL) {
267 clist_concat(session->imap_response_info->rsp_search_result,
268 mb_data->mbd_data.mbd_search);
269 clist_free(mb_data->mbd_data.mbd_search);
270 mb_data->mbd_data.mbd_search = NULL;
271 }
272 }
273 else {
274 if (mb_data->mbd_data.mbd_search != NULL) {
275 session->imap_response_info->rsp_search_result =
276 mb_data->mbd_data.mbd_search;
277 mb_data->mbd_data.mbd_search = NULL;
278 }
279 }
280 }
281 break;
282
283 case MAILIMAP_MAILBOX_DATA_STATUS:
284 if (session->imap_response_info) {
285 if (session->imap_response_info->rsp_status != NULL)
286 mailimap_mailbox_data_status_free(session->imap_response_info->rsp_status);
287 session->imap_response_info->rsp_status = mb_data->mbd_data.mbd_status;
288#if 0
289 if (session->imap_selection_info != NULL) {
290 clistiter * cur;
291
292 for(cur = clist_begin(mb_data->status->status_info_list)
293 ; cur != NULL ; cur = clist_next(cur)) {
294 struct mailimap_status_info * info;
295
296 info = clist_content(cur);
297 switch (info->att) {
298 case MAILIMAP_STATUS_ATT_MESSAGES:
299 session->imap_selection_info->exists = info->value;
300 break;
301 case MAILIMAP_STATUS_ATT_RECENT:
302 session->imap_selection_info->recent = info->value;
303 break;
304 case MAILIMAP_STATUS_ATT_UIDNEXT:
305 session->imap_selection_info->uidnext = info->value;
306 break;
307 case MAILIMAP_STATUS_ATT_UIDVALIDITY:
308 session->imap_selection_info->uidvalidity = info->value;
309 break;
310 case MAILIMAP_STATUS_ATT_UNSEEN:
311 session->imap_selection_info->unseen = info->value;
312 break;
313 }
314 }
315 }
316#endif
317#if 0
318 mailimap_mailbox_data_status_free(mb_data->status);
319#endif
320 mb_data->mbd_data.mbd_status = NULL;
321 }
322 break;
323
324 case MAILIMAP_MAILBOX_DATA_EXISTS:
325 if (session->imap_selection_info)
326 session->imap_selection_info->sel_exists = mb_data->mbd_data.mbd_exists;
327 break;
328
329 case MAILIMAP_MAILBOX_DATA_RECENT:
330 if (session->imap_selection_info)
331 session->imap_selection_info->sel_recent =
332 mb_data->mbd_data.mbd_recent;
333 break;
334 }
335}
336
337static void
338message_data_store(mailimap * session,
339 struct mailimap_message_data * msg_data)
340{
341 uint32_t * expunged;
342 int r;
343
344 switch (msg_data->mdt_type) {
345 case MAILIMAP_MESSAGE_DATA_EXPUNGE:
346 if (session->imap_response_info) {
347 expunged = mailimap_number_alloc_new(msg_data->mdt_number);
348 if (expunged != NULL) {
349 r = clist_append(session->imap_response_info->rsp_expunged, expunged);
350 if (r == 0) {
351 /* do nothing */
352 }
353 else {
354 /* TODO : must handle error case */
355 mailimap_number_alloc_free(expunged);
356 }
357 if (session->imap_selection_info != NULL)
358 session->imap_selection_info->sel_exists --;
359 }
360 }
361 break;
362
363 case MAILIMAP_MESSAGE_DATA_FETCH:
364 r = clist_append(session->imap_response_info->rsp_fetch_list,
365 msg_data->mdt_msg_att);
366 if (r == 0) {
367 msg_data->mdt_msg_att->att_number = msg_data->mdt_number;
368 msg_data->mdt_msg_att = NULL;
369 }
370 else {
371 /* TODO : must handle error case */
372 }
373 break;
374 }
375}
376
377static void
378cont_req_or_resp_data_store(mailimap * session,
379 struct mailimap_cont_req_or_resp_data * cont_req_or_resp_data)
380{
381 if (cont_req_or_resp_data->rsp_type == MAILIMAP_RESP_RESP_DATA) {
382 struct mailimap_response_data * resp_data;
383
384 resp_data = cont_req_or_resp_data->rsp_data.rsp_resp_data;
385
386 switch (resp_data->rsp_type) {
387 case MAILIMAP_RESP_DATA_TYPE_COND_STATE:
388 resp_cond_state_store(session, resp_data->rsp_data.rsp_cond_state);
389 break;
390 case MAILIMAP_RESP_DATA_TYPE_MAILBOX_DATA:
391 mailbox_data_store(session, resp_data->rsp_data.rsp_mailbox_data);
392 break;
393 case MAILIMAP_RESP_DATA_TYPE_MESSAGE_DATA:
394 message_data_store(session, resp_data->rsp_data.rsp_message_data);
395 break;
396 case MAILIMAP_RESP_DATA_TYPE_CAPABILITY_DATA:
397 if (session->imap_connection_info) {
398 if (session->imap_connection_info->imap_capability != NULL)
399 mailimap_capability_data_free(session->imap_connection_info->imap_capability);
400 session->imap_connection_info->imap_capability = resp_data->rsp_data.rsp_capability_data;
401 resp_data->rsp_data.rsp_capability_data = NULL;
402 }
403 break;
404 }
405 }
406}
407
408static void response_tagged_store(mailimap * session,
409 struct mailimap_response_tagged * tagged)
410{
411 resp_cond_state_store(session, tagged->rsp_cond_state);
412}
413
414static void resp_cond_bye_store(mailimap * session,
415 struct mailimap_resp_cond_bye * resp_cond_bye)
416{
417 resp_text_store(session, resp_cond_bye->rsp_text);
418}
419
420static void response_fatal_store(mailimap * session,
421 struct mailimap_response_fatal * fatal)
422{
423 resp_cond_bye_store(session, fatal->rsp_bye);
424}
425
426static void response_done_store(mailimap * session,
427 struct mailimap_response_done * resp_done)
428{
429 switch(resp_done->rsp_type) {
430 case MAILIMAP_RESP_DONE_TYPE_TAGGED:
431 response_tagged_store(session, resp_done->rsp_data.rsp_tagged);
432 break;
433 case MAILIMAP_RESP_DONE_TYPE_FATAL:
434 response_fatal_store(session, resp_done->rsp_data.rsp_fatal);
435 break;
436 }
437}
438
439static void
440response_store(mailimap * session,
441 struct mailimap_response * response)
442{
443 clistiter * cur;
444
445 if (session->imap_response_info) {
446 mailimap_response_info_free(session->imap_response_info);
447 session->imap_response_info = NULL;
448 }
449
450 session->imap_response_info = mailimap_response_info_new();
451 if (session->imap_response_info == NULL) {
452 /* ignored error */
453 return;
454 }
455
456 if (response->rsp_cont_req_or_resp_data_list != NULL) {
457 for(cur = clist_begin(response->rsp_cont_req_or_resp_data_list) ;
458 cur != NULL ; cur = clist_next(cur)) {
459 struct mailimap_cont_req_or_resp_data * cont_req_or_resp_data;
460
461 cont_req_or_resp_data = clist_content(cur);
462
463 cont_req_or_resp_data_store(session, cont_req_or_resp_data);
464 }
465 }
466
467 response_done_store(session, response->rsp_resp_done);
468}
469
470static void resp_cond_auth_store(mailimap * session,
471 struct mailimap_resp_cond_auth * cond_auth)
472{
473 resp_text_store(session, cond_auth->rsp_text);
474}
475
476static void greeting_store(mailimap * session,
477 struct mailimap_greeting * greeting)
478{
479 switch (greeting->gr_type) {
480 case MAILIMAP_GREETING_RESP_COND_AUTH:
481 resp_cond_auth_store(session, greeting->gr_data.gr_auth);
482 break;
483
484 case MAILIMAP_GREETING_RESP_COND_BYE:
485 resp_cond_bye_store(session, greeting->gr_data.gr_bye);
486 break;
487 }
488}
489
490int mailimap_connect(mailimap * session, mailstream * s)
491{
492 struct mailimap_greeting * greeting;
493 int r;
494 int auth_type;
495 struct mailimap_connection_info * connection_info;
496
497 if (session->imap_state != MAILIMAP_STATE_DISCONNECTED)
498 return MAILIMAP_ERROR_BAD_STATE;
499
500 session->imap_stream = s;
501
502 if (session->imap_connection_info)
503 mailimap_connection_info_free(session->imap_connection_info);
504 connection_info = mailimap_connection_info_new();
505 if (connection_info != NULL)
506 session->imap_connection_info = connection_info;
507
508 if (read_line(session) == NULL) {
509 return MAILIMAP_ERROR_STREAM;
510 }
511
512 r = parse_greeting(session, &greeting);
513 if (r != MAILIMAP_NO_ERROR) {
514 return r;
515 }
516
517 auth_type = greeting->gr_data.gr_auth->rsp_type;
518
519 mailimap_greeting_free(greeting);
520
521 switch (auth_type) {
522 case MAILIMAP_RESP_COND_AUTH_PREAUTH:
523 session->imap_state = MAILIMAP_STATE_AUTHENTICATED;
524 return MAILIMAP_NO_ERROR_AUTHENTICATED;
525 default:
526 session->imap_state = MAILIMAP_STATE_NON_AUTHENTICATED;
527 return MAILIMAP_NO_ERROR_NON_AUTHENTICATED;
528 }
529}
530
531
532
533
534
535
536
537
538/* ********************************************************************** */
539
540
541
542int mailimap_append(mailimap * session, const char * mailbox,
543 struct mailimap_flag_list * flag_list,
544 struct mailimap_date_time * date_time,
545 const char * literal, size_t literal_size)
546{
547 struct mailimap_response * response;
548 int r;
549 int error_code;
550 struct mailimap_continue_req * cont_req;
551 size_t index;
552
553 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
554 (session->imap_state != MAILIMAP_STATE_SELECTED))
555 return MAILIMAP_ERROR_BAD_STATE;
556
557 r = send_current_tag(session);
558 if (r != MAILIMAP_NO_ERROR)
559 return r;
560
561 r = mailimap_append_send(session->imap_stream, mailbox, flag_list, date_time,
562 literal_size);
563 if (r != MAILIMAP_NO_ERROR)
564 return r;
565
566 if (mailstream_flush(session->imap_stream) == -1)
567 return MAILIMAP_ERROR_STREAM;
568
569 if (read_line(session) == NULL)
570 return MAILIMAP_ERROR_STREAM;
571
572 index = 0;
573
574 r = mailimap_continue_req_parse(session->imap_stream,
575 session->imap_stream_buffer,
576 &index, &cont_req,
577 session->imap_progr_rate, session->imap_progr_fun);
578 if (r == MAILIMAP_NO_ERROR)
579 mailimap_continue_req_free(cont_req);
580
581 if (r == MAILIMAP_ERROR_PARSE) {
582 r = parse_response(session, &response);
583 if (r != MAILIMAP_NO_ERROR)
584 return r;
585 mailimap_response_free(response);
586
587 return MAILIMAP_ERROR_APPEND;
588 }
589
590 r = mailimap_literal_data_send(session->imap_stream, literal, literal_size,
591 session->imap_progr_rate, session->imap_progr_fun);
592 if (r != MAILIMAP_NO_ERROR)
593 return r;
594
595 r = mailimap_crlf_send(session->imap_stream);
596 if (r != MAILIMAP_NO_ERROR)
597 return r;
598
599 if (mailstream_flush(session->imap_stream) == -1)
600 return MAILIMAP_ERROR_STREAM;
601
602 if (read_line(session) == NULL)
603 return MAILIMAP_ERROR_STREAM;
604
605 r = parse_response(session, &response);
606 if (r != MAILIMAP_NO_ERROR)
607 return r;
608
609 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
610
611 mailimap_response_free(response);
612
613 switch (error_code) {
614 case MAILIMAP_RESP_COND_STATE_OK:
615 return MAILIMAP_NO_ERROR;
616
617 default:
618 return MAILIMAP_ERROR_APPEND;
619 }
620}
621
622/*
623gboolean mailimap_authenticate(mailimap * session,
624 gchar * auth_type)
625{
626}
627
628gboolean mailimap_authenticate_resp_send(mailimap * session,
629 gchar * base64)
630{
631}
632*/
633
634int mailimap_noop(mailimap * session)
635{
636 struct mailimap_response * response;
637 int r;
638 int error_code;
639
640 r = send_current_tag(session);
641 if (r != MAILIMAP_NO_ERROR)
642 return r;
643
644 r = mailimap_noop_send(session->imap_stream);
645 if (r != MAILIMAP_NO_ERROR)
646 return r;
647
648 r = mailimap_crlf_send(session->imap_stream);
649 if (r != MAILIMAP_NO_ERROR)
650 return r;
651
652 if (mailstream_flush(session->imap_stream) == -1)
653 return MAILIMAP_ERROR_STREAM;
654
655 if (read_line(session) == NULL)
656 return MAILIMAP_ERROR_STREAM;
657
658 r = parse_response(session, &response);
659 if (r != MAILIMAP_NO_ERROR)
660 return r;
661
662 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
663
664 mailimap_response_free(response);
665
666 switch (error_code) {
667 case MAILIMAP_RESP_COND_STATE_OK:
668 return MAILIMAP_NO_ERROR;
669
670 default:
671 return MAILIMAP_ERROR_NOOP;
672 }
673}
674
675int mailimap_logout(mailimap * session)
676{
677 struct mailimap_response * response;
678 int r;
679 int error_code;
680 int res;
681
682 r = send_current_tag(session);
683 if (r != MAILIMAP_NO_ERROR) {
684 res = r;
685 goto close;
686 }
687
688 r = mailimap_logout_send(session->imap_stream);
689 if (r != MAILIMAP_NO_ERROR) {
690 res = r;
691 goto close;
692 }
693
694 r = mailimap_crlf_send(session->imap_stream);
695 if (r != MAILIMAP_NO_ERROR) {
696 res = r;
697 goto close;
698 }
699
700 if (mailstream_flush(session->imap_stream) == -1) {
701 res = MAILIMAP_ERROR_STREAM;
702 goto close;
703 }
704
705 if (read_line(session) == NULL) {
706 res = MAILIMAP_ERROR_STREAM;
707 goto close;
708 }
709
710 r = parse_response(session, &response);
711 if (r != MAILIMAP_NO_ERROR) {
712 res = r;
713 goto close;
714 }
715
716 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
717
718 mailimap_response_free(response);
719
720 switch (error_code) {
721 case MAILIMAP_RESP_COND_STATE_OK:
722 if (session->imap_connection_info) {
723 mailimap_connection_info_free(session->imap_connection_info);
724 session->imap_connection_info = NULL;
725 }
726 res = MAILIMAP_NO_ERROR;
727 goto close;
728
729 default:
730 res = MAILIMAP_ERROR_LOGOUT;
731 goto close;
732 }
733
734 close:
735 mailstream_close(session->imap_stream);
736 session->imap_stream = NULL;
737 session->imap_state = MAILIMAP_STATE_DISCONNECTED;
738 return res;
739}
740
741/* send the results back to the caller */
742/* duplicate the result */
743
744static struct mailimap_capability *
745mailimap_capability_dup(struct mailimap_capability * orig_cap)
746{
747 struct mailimap_capability * cap;
748 char * auth_type;
749 char * name;
750
751 name = NULL;
752 auth_type = NULL;
753 switch (orig_cap->cap_type) {
754 case MAILIMAP_CAPABILITY_NAME:
755 name = strdup(orig_cap->cap_data.cap_name);
756 if (name == NULL)
757 goto err;
758 break;
759 case MAILIMAP_CAPABILITY_AUTH_TYPE:
760 auth_type = strdup(orig_cap->cap_data.cap_auth_type);
761 if (auth_type == NULL)
762 goto err;
763 break;
764 }
765
766 cap = mailimap_capability_new(orig_cap->cap_type, auth_type, name);
767 if (cap == NULL)
768 goto free;
769
770 return cap;
771
772 free:
773 if (name != NULL)
774 free(name);
775 if (auth_type != NULL)
776 free(auth_type);
777 err:
778 return NULL;
779}
780
781static struct mailimap_capability_data *
782mailimap_capability_data_dup(struct mailimap_capability_data * orig_cap_data)
783{
784 struct mailimap_capability_data * cap_data;
785 struct mailimap_capability * cap_dup;
786 clist * list;
787 clistiter * cur;
788 int r;
789
790 list = clist_new();
791 if (list == NULL)
792 goto err;
793
794 for(cur = clist_begin(orig_cap_data->cap_list) ;
795 cur != NULL ; cur = clist_next(cur)) {
796 struct mailimap_capability * cap;
797
798 cap = clist_content(cur);
799
800 cap_dup = mailimap_capability_dup(cap);
801 if (cap_dup == NULL)
802 goto list;
803
804 r = clist_append(list, cap_dup);
805 if (r < 0) {
806 mailimap_capability_free(cap_dup);
807 goto list;
808 }
809 }
810
811 cap_data = mailimap_capability_data_new(list);
812 if (cap_data == NULL)
813 goto list;
814
815 return cap_data;
816
817list:
818 clist_foreach(list, (clist_func) mailimap_capability_free, NULL);
819 clist_free(list);
820err:
821 return NULL;
822}
823
824int mailimap_capability(mailimap * session,
825 struct mailimap_capability_data ** result)
826{
827 struct mailimap_response * response;
828 int r;
829 int error_code;
830 struct mailimap_capability_data * cap_data;
831
832 r = send_current_tag(session);
833 if (r != MAILIMAP_NO_ERROR)
834 return r;
835
836 r = mailimap_capability_send(session->imap_stream);
837 if (r != MAILIMAP_NO_ERROR)
838 return r;
839
840 r = mailimap_crlf_send(session->imap_stream);
841 if (r != MAILIMAP_NO_ERROR)
842 return r;
843
844 if (mailstream_flush(session->imap_stream) == -1)
845 return MAILIMAP_ERROR_STREAM;
846
847 if (read_line(session) == NULL)
848 return MAILIMAP_ERROR_STREAM;
849
850 r = parse_response(session, &response);
851 if (r != MAILIMAP_NO_ERROR)
852 return r;
853
854 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
855
856 mailimap_response_free(response);
857
858 switch (error_code) {
859 case MAILIMAP_RESP_COND_STATE_OK:
860 cap_data =
861 mailimap_capability_data_dup(session->imap_connection_info->imap_capability);
862 if (cap_data == NULL)
863 return MAILIMAP_ERROR_MEMORY;
864
865 * result = cap_data;
866
867 return MAILIMAP_NO_ERROR;
868
869 default:
870 return MAILIMAP_ERROR_CAPABILITY;
871 }
872}
873
874int mailimap_check(mailimap * session)
875{
876 struct mailimap_response * response;
877 int r;
878 int error_code;
879
880 if (session->imap_state != MAILIMAP_STATE_SELECTED)
881 return MAILIMAP_ERROR_BAD_STATE;
882
883 r = send_current_tag(session);
884 if (r != MAILIMAP_NO_ERROR)
885 return r;
886
887 r = mailimap_check_send(session->imap_stream);
888 if (r != MAILIMAP_NO_ERROR)
889 return r;
890
891 r = mailimap_crlf_send(session->imap_stream);
892 if (r != MAILIMAP_NO_ERROR)
893 return r;
894
895 if (mailstream_flush(session->imap_stream) == -1)
896 return MAILIMAP_ERROR_STREAM;
897
898 if (read_line(session) == NULL)
899 return MAILIMAP_ERROR_STREAM;
900
901 r = parse_response(session, &response);
902 if (r != MAILIMAP_NO_ERROR)
903 return r;
904
905 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
906
907 mailimap_response_free(response);
908
909 switch (error_code) {
910 case MAILIMAP_RESP_COND_STATE_OK:
911 return MAILIMAP_NO_ERROR;
912
913 default:
914 return MAILIMAP_ERROR_CHECK;
915 }
916}
917
918int mailimap_close(mailimap * session)
919{
920 struct mailimap_response * response;
921 int r;
922 int error_code;
923
924 if (session->imap_state != MAILIMAP_STATE_SELECTED)
925 return MAILIMAP_ERROR_BAD_STATE;
926
927 r = send_current_tag(session);
928 if (r != MAILIMAP_NO_ERROR)
929 return r;
930
931 r = mailimap_close_send(session->imap_stream);
932 if (r != MAILIMAP_NO_ERROR)
933 return r;
934
935 r = mailimap_crlf_send(session->imap_stream);
936 if (r != MAILIMAP_NO_ERROR)
937 return r;
938
939 if (mailstream_flush(session->imap_stream) == -1)
940 return MAILIMAP_ERROR_STREAM;
941
942 if (read_line(session) == NULL)
943 return MAILIMAP_ERROR_STREAM;
944
945 r = parse_response(session, &response);
946 if (r != MAILIMAP_NO_ERROR)
947 return r;
948
949 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
950
951 mailimap_response_free(response);
952
953 switch (error_code) {
954 case MAILIMAP_RESP_COND_STATE_OK:
955 /* leave selected state */
956 mailimap_selection_info_free(session->imap_selection_info);
957 session->imap_selection_info = NULL;
958
959 session->imap_state = MAILIMAP_STATE_AUTHENTICATED;
960 return MAILIMAP_NO_ERROR;
961
962 default:
963 return MAILIMAP_ERROR_CLOSE;
964 }
965}
966
967int mailimap_expunge(mailimap * session)
968{
969 struct mailimap_response * response;
970 int r;
971 int error_code;
972
973 if (session->imap_state != MAILIMAP_STATE_SELECTED)
974 return MAILIMAP_ERROR_BAD_STATE;
975
976 r = send_current_tag(session);
977 if (r != MAILIMAP_NO_ERROR)
978 return r;
979
980 r = mailimap_expunge_send(session->imap_stream);
981 if (r != MAILIMAP_NO_ERROR)
982 return r;
983
984 r = mailimap_crlf_send(session->imap_stream);
985 if (r != MAILIMAP_NO_ERROR)
986 return r;
987
988 if (mailstream_flush(session->imap_stream) == -1)
989 return MAILIMAP_ERROR_STREAM;
990
991 if (read_line(session) == NULL)
992 return MAILIMAP_ERROR_STREAM;
993
994 r = parse_response(session, &response);
995 if (r != MAILIMAP_NO_ERROR)
996 return r;
997
998 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
999
1000 mailimap_response_free(response);
1001
1002 switch (error_code) {
1003 case MAILIMAP_RESP_COND_STATE_OK:
1004 return MAILIMAP_NO_ERROR;
1005
1006 default:
1007 return MAILIMAP_ERROR_EXPUNGE;
1008 }
1009}
1010
1011int mailimap_copy(mailimap * session, struct mailimap_set * set,
1012 const char * mb)
1013{
1014 struct mailimap_response * response;
1015 int r;
1016 int error_code;
1017
1018 if (session->imap_state != MAILIMAP_STATE_SELECTED)
1019 return MAILIMAP_ERROR_BAD_STATE;
1020
1021 r = send_current_tag(session);
1022 if (r != MAILIMAP_NO_ERROR)
1023 return r;
1024
1025 r = mailimap_copy_send(session->imap_stream, set, mb);
1026 if (r != MAILIMAP_NO_ERROR)
1027 return r;
1028
1029 r = mailimap_crlf_send(session->imap_stream);
1030 if (r != MAILIMAP_NO_ERROR)
1031 return r;
1032
1033 if (mailstream_flush(session->imap_stream) == -1)
1034 return MAILIMAP_ERROR_STREAM;
1035
1036 if (read_line(session) == NULL)
1037 return MAILIMAP_ERROR_STREAM;
1038
1039 r = parse_response(session, &response);
1040 if (r != MAILIMAP_NO_ERROR)
1041 return r;
1042
1043 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1044
1045 mailimap_response_free(response);
1046
1047 switch (error_code) {
1048 case MAILIMAP_RESP_COND_STATE_OK:
1049 return MAILIMAP_NO_ERROR;
1050
1051 default:
1052 return MAILIMAP_ERROR_COPY;
1053 }
1054}
1055
1056int mailimap_uid_copy(mailimap * session, struct mailimap_set * set,
1057 const char * mb)
1058{
1059 struct mailimap_response * response;
1060 int r;
1061 int error_code;
1062
1063 if (session->imap_state != MAILIMAP_STATE_SELECTED)
1064 return MAILIMAP_ERROR_BAD_STATE;
1065
1066 r = send_current_tag(session);
1067 if (r != MAILIMAP_NO_ERROR)
1068 return r;
1069
1070 r = mailimap_uid_copy_send(session->imap_stream, set, mb);
1071 if (r != MAILIMAP_NO_ERROR)
1072 return r;
1073
1074 r = mailimap_crlf_send(session->imap_stream);
1075 if (r != MAILIMAP_NO_ERROR)
1076 return r;
1077
1078 if (mailstream_flush(session->imap_stream) == -1)
1079 return MAILIMAP_ERROR_STREAM;
1080
1081 if (read_line(session) == NULL)
1082 return MAILIMAP_ERROR_STREAM;
1083
1084 r = parse_response(session, &response);
1085 if (r != MAILIMAP_NO_ERROR)
1086 return r;
1087
1088 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1089
1090 mailimap_response_free(response);
1091
1092 switch (error_code) {
1093 case MAILIMAP_RESP_COND_STATE_OK:
1094 return MAILIMAP_NO_ERROR;
1095
1096 default:
1097 return MAILIMAP_ERROR_UID_COPY;
1098 }
1099}
1100
1101int mailimap_create(mailimap * session, const char * mb)
1102{
1103 struct mailimap_response * response;
1104 int r;
1105 int error_code;
1106
1107 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1108 (session->imap_state != MAILIMAP_STATE_SELECTED))
1109 return MAILIMAP_ERROR_BAD_STATE;
1110
1111 r = send_current_tag(session);
1112 if (r != MAILIMAP_NO_ERROR)
1113 return r;
1114
1115 r = mailimap_create_send(session->imap_stream, mb);
1116 if (r != MAILIMAP_NO_ERROR)
1117 return r;
1118
1119 r = mailimap_crlf_send(session->imap_stream);
1120 if (r != MAILIMAP_NO_ERROR)
1121 return r;
1122
1123 if (mailstream_flush(session->imap_stream) == -1)
1124 return MAILIMAP_ERROR_STREAM;
1125
1126 if (read_line(session) == NULL)
1127 return MAILIMAP_ERROR_STREAM;
1128
1129 r = parse_response(session, &response);
1130 if (r != MAILIMAP_NO_ERROR)
1131 return r;
1132
1133 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1134
1135 mailimap_response_free(response);
1136
1137 switch (error_code) {
1138 case MAILIMAP_RESP_COND_STATE_OK:
1139 return MAILIMAP_NO_ERROR;
1140
1141 default:
1142 return MAILIMAP_ERROR_CREATE;
1143 }
1144}
1145
1146
1147int mailimap_delete(mailimap * session, const char * mb)
1148{
1149 struct mailimap_response * response;
1150 int r;
1151 int error_code;
1152
1153 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1154 (session->imap_state != MAILIMAP_STATE_SELECTED))
1155 return MAILIMAP_ERROR_BAD_STATE;
1156
1157 r = send_current_tag(session);
1158 if (r != MAILIMAP_NO_ERROR)
1159 return r;
1160
1161 r = mailimap_delete_send(session->imap_stream, mb);
1162 if (r != MAILIMAP_NO_ERROR)
1163 return r;
1164
1165 r = mailimap_crlf_send(session->imap_stream);
1166 if (r != MAILIMAP_NO_ERROR)
1167 return r;
1168
1169 if (mailstream_flush(session->imap_stream) == -1)
1170 return MAILIMAP_ERROR_STREAM;
1171
1172 if (read_line(session) == NULL)
1173 return MAILIMAP_ERROR_STREAM;
1174
1175 r = parse_response(session, &response);
1176 if (r != MAILIMAP_NO_ERROR)
1177 return r;
1178
1179 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1180
1181 mailimap_response_free(response);
1182
1183 switch (error_code) {
1184 case MAILIMAP_RESP_COND_STATE_OK:
1185 return MAILIMAP_NO_ERROR;
1186
1187 default:
1188 return MAILIMAP_ERROR_DELETE;
1189 }
1190}
1191
1192int mailimap_examine(mailimap * session, const char * mb)
1193{
1194 struct mailimap_response * response;
1195 int r;
1196 int error_code;
1197
1198 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1199 (session->imap_state != MAILIMAP_STATE_SELECTED))
1200 return MAILIMAP_ERROR_BAD_STATE;
1201
1202 r = send_current_tag(session);
1203 if (r != MAILIMAP_NO_ERROR)
1204 return r;
1205
1206 r = mailimap_examine_send(session->imap_stream, mb);
1207 if (r != MAILIMAP_NO_ERROR)
1208 return r;
1209
1210 r = mailimap_crlf_send(session->imap_stream);
1211 if (r != MAILIMAP_NO_ERROR)
1212 return r;
1213
1214 if (mailstream_flush(session->imap_stream) == -1)
1215 return MAILIMAP_ERROR_STREAM;
1216
1217 if (read_line(session) == NULL)
1218 return MAILIMAP_ERROR_STREAM;
1219
1220 if (session->imap_selection_info != NULL)
1221 mailimap_selection_info_free(session->imap_selection_info);
1222 session->imap_selection_info = mailimap_selection_info_new();
1223
1224 r = parse_response(session, &response);
1225 if (r != MAILIMAP_NO_ERROR)
1226 return r;
1227
1228 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1229
1230 mailimap_response_free(response);
1231
1232 switch (error_code) {
1233 case MAILIMAP_RESP_COND_STATE_OK:
1234 session->imap_state = MAILIMAP_STATE_SELECTED;
1235 return MAILIMAP_NO_ERROR;
1236
1237 default:
1238 mailimap_selection_info_free(session->imap_selection_info);
1239 session->imap_selection_info = NULL;
1240 session->imap_state = MAILIMAP_STATE_AUTHENTICATED;
1241 return MAILIMAP_ERROR_EXAMINE;
1242 }
1243}
1244
1245int
1246mailimap_fetch(mailimap * session, struct mailimap_set * set,
1247 struct mailimap_fetch_type * fetch_type, clist ** result)
1248{
1249 struct mailimap_response * response;
1250 int r;
1251 int error_code;
1252
1253 if (session->imap_state != MAILIMAP_STATE_SELECTED)
1254 return MAILIMAP_ERROR_BAD_STATE;
1255
1256 r = send_current_tag(session);
1257 if (r != MAILIMAP_NO_ERROR)
1258 return r;
1259
1260 r = mailimap_fetch_send(session->imap_stream, set, fetch_type);
1261 if (r != MAILIMAP_NO_ERROR)
1262 return r;
1263
1264 r = mailimap_crlf_send(session->imap_stream);
1265 if (r != MAILIMAP_NO_ERROR)
1266 return r;
1267
1268 if (mailstream_flush(session->imap_stream) == -1)
1269 return MAILIMAP_ERROR_STREAM;
1270
1271 if (read_line(session) == NULL)
1272 return MAILIMAP_ERROR_STREAM;
1273
1274 r = parse_response(session, &response);
1275 if (r != MAILIMAP_NO_ERROR)
1276 return r;
1277
1278 * result = session->imap_response_info->rsp_fetch_list;
1279 session->imap_response_info->rsp_fetch_list = NULL;
1280
1281 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1282
1283 mailimap_response_free(response);
1284
1285 switch (error_code) {
1286 case MAILIMAP_RESP_COND_STATE_OK:
1287 return MAILIMAP_NO_ERROR;
1288
1289 default:
1290 return MAILIMAP_ERROR_FETCH;
1291 }
1292}
1293
1294void mailimap_fetch_list_free(clist * fetch_list)
1295{
1296 clist_foreach(fetch_list, (clist_func) mailimap_msg_att_free, NULL);
1297 clist_free(fetch_list);
1298}
1299
1300int
1301mailimap_uid_fetch(mailimap * session,
1302 struct mailimap_set * set,
1303 struct mailimap_fetch_type * fetch_type, clist ** result)
1304{
1305 struct mailimap_response * response;
1306 int r;
1307 int error_code;
1308
1309 if (session->imap_state != MAILIMAP_STATE_SELECTED)
1310 return MAILIMAP_ERROR_BAD_STATE;
1311
1312 r = send_current_tag(session);
1313 if (r != MAILIMAP_NO_ERROR)
1314 return r;
1315
1316 r = mailimap_uid_fetch_send(session->imap_stream, set, fetch_type);
1317 if (r != MAILIMAP_NO_ERROR)
1318 return r;
1319
1320 r = mailimap_crlf_send(session->imap_stream);
1321 if (r != MAILIMAP_NO_ERROR)
1322 return r;
1323
1324 if (mailstream_flush(session->imap_stream) == -1)
1325 return MAILIMAP_ERROR_STREAM;
1326
1327 if (read_line(session) == NULL)
1328 return MAILIMAP_ERROR_STREAM;
1329
1330 r = parse_response(session, &response);
1331
1332 if (r != MAILIMAP_NO_ERROR)
1333 return r;
1334
1335 * result = session->imap_response_info->rsp_fetch_list;
1336 session->imap_response_info->rsp_fetch_list = NULL;
1337
1338 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1339
1340 mailimap_response_free(response);
1341
1342 switch (error_code) {
1343 case MAILIMAP_RESP_COND_STATE_OK:
1344 return MAILIMAP_NO_ERROR;
1345
1346 default:
1347 return MAILIMAP_ERROR_UID_FETCH;
1348 }
1349}
1350
1351int mailimap_list(mailimap * session, const char * mb,
1352 const char * list_mb, clist ** result)
1353{
1354 struct mailimap_response * response;
1355 int r;
1356 int error_code;
1357
1358 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1359 (session->imap_state != MAILIMAP_STATE_SELECTED))
1360 return MAILIMAP_ERROR_BAD_STATE;
1361
1362 r = send_current_tag(session);
1363 if (r != MAILIMAP_NO_ERROR)
1364 return r;
1365
1366 r = mailimap_list_send(session->imap_stream, mb, list_mb);
1367 if (r != MAILIMAP_NO_ERROR)
1368 return r;
1369
1370 r = mailimap_crlf_send(session->imap_stream);
1371 if (r != MAILIMAP_NO_ERROR)
1372 return r;
1373
1374 if (mailstream_flush(session->imap_stream) == -1)
1375 return MAILIMAP_ERROR_STREAM;
1376
1377 if (read_line(session) == NULL)
1378 return MAILIMAP_ERROR_STREAM;
1379
1380 r = parse_response(session, &response);
1381 if (r != MAILIMAP_NO_ERROR)
1382 return r;
1383
1384 * result = session->imap_response_info->rsp_mailbox_list;
1385 session->imap_response_info->rsp_mailbox_list = NULL;
1386
1387 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1388
1389 mailimap_response_free(response);
1390
1391 switch (error_code) {
1392 case MAILIMAP_RESP_COND_STATE_OK:
1393 return MAILIMAP_NO_ERROR;
1394
1395 default:
1396 return MAILIMAP_ERROR_LIST;
1397 }
1398}
1399
1400int mailimap_login(mailimap * session,
1401 const char * userid, const char * password)
1402{
1403 struct mailimap_response * response;
1404 int r;
1405 int error_code;
1406
1407 if (session->imap_state != MAILIMAP_STATE_NON_AUTHENTICATED)
1408 return MAILIMAP_ERROR_BAD_STATE;
1409
1410 r = send_current_tag(session);
1411 if (r != MAILIMAP_NO_ERROR)
1412 return r;
1413
1414 r = mailimap_login_send(session->imap_stream, userid, password);
1415 if (r != MAILIMAP_NO_ERROR)
1416 return r;
1417
1418 r = mailimap_crlf_send(session->imap_stream);
1419 if (r != MAILIMAP_NO_ERROR)
1420 return r;
1421
1422 if (mailstream_flush(session->imap_stream) == -1)
1423 return MAILIMAP_ERROR_STREAM;
1424
1425 if (read_line(session) == NULL)
1426 return MAILIMAP_ERROR_STREAM;
1427
1428 r = parse_response(session, &response);
1429 if (r != MAILIMAP_NO_ERROR)
1430 return r;
1431
1432 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1433
1434 mailimap_response_free(response);
1435
1436 switch (error_code) {
1437 case MAILIMAP_RESP_COND_STATE_OK:
1438 session->imap_state = MAILIMAP_STATE_AUTHENTICATED;
1439 return MAILIMAP_NO_ERROR;
1440
1441 default:
1442 return MAILIMAP_ERROR_LOGIN;
1443 }
1444}
1445
1446int mailimap_lsub(mailimap * session, const char * mb,
1447 const char * list_mb, clist ** result)
1448{
1449 struct mailimap_response * response;
1450 int r;
1451 int error_code;
1452
1453 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1454 (session->imap_state != MAILIMAP_STATE_SELECTED))
1455 return MAILIMAP_ERROR_BAD_STATE;
1456
1457 r = send_current_tag(session);
1458 if (r != MAILIMAP_NO_ERROR)
1459 return r;
1460
1461 r = mailimap_lsub_send(session->imap_stream, mb, list_mb);
1462 if (r != MAILIMAP_NO_ERROR)
1463 return r;
1464
1465 r = mailimap_crlf_send(session->imap_stream);
1466 if (r != MAILIMAP_NO_ERROR)
1467 return r;
1468
1469 if (mailstream_flush(session->imap_stream) == -1)
1470 return MAILIMAP_ERROR_STREAM;
1471
1472 if (read_line(session) == NULL)
1473 return MAILIMAP_ERROR_STREAM;
1474
1475 r = parse_response(session, &response);
1476 if (r != MAILIMAP_NO_ERROR)
1477 return r;
1478
1479 * result = session->imap_response_info->rsp_mailbox_lsub;
1480 session->imap_response_info->rsp_mailbox_lsub = NULL;
1481
1482 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1483
1484 mailimap_response_free(response);
1485
1486 switch (error_code) {
1487 case MAILIMAP_RESP_COND_STATE_OK:
1488 return MAILIMAP_NO_ERROR;
1489
1490 default:
1491 return MAILIMAP_ERROR_LSUB;
1492 }
1493}
1494
1495void mailimap_list_result_free(clist * list)
1496{
1497 clist_foreach(list, (clist_func) mailimap_mailbox_list_free, NULL);
1498 clist_free(list);
1499}
1500
1501int mailimap_rename(mailimap * session,
1502 const char * mb, const char * new_name)
1503{
1504 struct mailimap_response * response;
1505 int r;
1506 int error_code;
1507
1508 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1509 (session->imap_state != MAILIMAP_STATE_SELECTED))
1510 return MAILIMAP_ERROR_BAD_STATE;
1511
1512 r = send_current_tag(session);
1513 if (r != MAILIMAP_NO_ERROR)
1514 return r;
1515
1516 r = mailimap_rename_send(session->imap_stream, mb, new_name);
1517 if (r != MAILIMAP_NO_ERROR)
1518 return r;
1519
1520 if (!mailimap_crlf_send(session->imap_stream))
1521 if (r != MAILIMAP_NO_ERROR)
1522 return r;
1523
1524 if (mailstream_flush(session->imap_stream) == -1)
1525 return MAILIMAP_ERROR_STREAM;
1526
1527 if (read_line(session) == NULL)
1528 return MAILIMAP_ERROR_STREAM;
1529
1530 r = parse_response(session, &response);
1531 if (r != MAILIMAP_NO_ERROR)
1532 return r;
1533
1534 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1535
1536 mailimap_response_free(response);
1537
1538 switch (error_code) {
1539 case MAILIMAP_RESP_COND_STATE_OK:
1540 return MAILIMAP_NO_ERROR;
1541
1542 default:
1543 return MAILIMAP_ERROR_RENAME;
1544 }
1545}
1546
1547int
1548mailimap_search(mailimap * session, const char * charset,
1549 struct mailimap_search_key * key, clist ** result)
1550{
1551 struct mailimap_response * response;
1552 int r;
1553 int error_code;
1554
1555 if (session->imap_state != MAILIMAP_STATE_SELECTED)
1556 return MAILIMAP_ERROR_BAD_STATE;
1557
1558 r = send_current_tag(session);
1559 if (r != MAILIMAP_NO_ERROR)
1560 return r;
1561
1562 r = mailimap_search_send(session->imap_stream, charset, key);
1563 if (r != MAILIMAP_NO_ERROR)
1564 return r;
1565
1566 r = mailimap_crlf_send(session->imap_stream);
1567 if (r != MAILIMAP_NO_ERROR)
1568 return r;
1569
1570 if (mailstream_flush(session->imap_stream) == -1)
1571 return MAILIMAP_ERROR_STREAM;
1572
1573 if (read_line(session) == NULL)
1574 return MAILIMAP_ERROR_STREAM;
1575
1576 r = parse_response(session, &response);
1577 if (r != MAILIMAP_NO_ERROR)
1578 return r;
1579
1580 * result = session->imap_response_info->rsp_search_result;
1581 session->imap_response_info->rsp_search_result = NULL;
1582
1583 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1584
1585 mailimap_response_free(response);
1586
1587 switch (error_code) {
1588 case MAILIMAP_RESP_COND_STATE_OK:
1589 return MAILIMAP_NO_ERROR;
1590
1591 default:
1592 return MAILIMAP_ERROR_SEARCH;
1593 }
1594}
1595
1596int
1597mailimap_uid_search(mailimap * session, const char * charset,
1598 struct mailimap_search_key * key, clist ** result)
1599{
1600 struct mailimap_response * response;
1601 int r;
1602 int error_code;
1603
1604 if (session->imap_state != MAILIMAP_STATE_SELECTED)
1605 return MAILIMAP_ERROR_BAD_STATE;
1606
1607 r = send_current_tag(session);
1608 if (r != MAILIMAP_NO_ERROR)
1609 return r;
1610
1611 r = mailimap_uid_search_send(session->imap_stream, charset, key);
1612 if (r != MAILIMAP_NO_ERROR)
1613 return r;
1614
1615 r = mailimap_crlf_send(session->imap_stream);
1616 if (r != MAILIMAP_NO_ERROR)
1617 return r;
1618
1619 if (mailstream_flush(session->imap_stream) == -1)
1620 return MAILIMAP_ERROR_STREAM;
1621
1622 if (read_line(session) == NULL)
1623 return MAILIMAP_ERROR_STREAM;
1624
1625 r = parse_response(session, &response);
1626 if (r != MAILIMAP_NO_ERROR)
1627 return r;
1628
1629 * result = session->imap_response_info->rsp_search_result;
1630 session->imap_response_info->rsp_search_result = NULL;
1631
1632 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1633
1634 mailimap_response_free(response);
1635
1636 switch (error_code) {
1637 case MAILIMAP_RESP_COND_STATE_OK:
1638 return MAILIMAP_NO_ERROR;
1639
1640 default:
1641 return MAILIMAP_ERROR_UID_SEARCH;
1642 }
1643}
1644
1645void mailimap_search_result_free(clist * search_result)
1646{
1647 clist_foreach(search_result, (clist_func) free, NULL);
1648 clist_free(search_result);
1649}
1650
1651int
1652mailimap_select(mailimap * session, const char * mb)
1653{
1654 struct mailimap_response * response;
1655 int r;
1656 int error_code;
1657
1658 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1659 (session->imap_state != MAILIMAP_STATE_SELECTED))
1660 return MAILIMAP_ERROR_BAD_STATE;
1661
1662 r = send_current_tag(session);
1663 if (r != MAILIMAP_NO_ERROR)
1664 return r;
1665
1666 r = mailimap_select_send(session->imap_stream, mb);
1667 if (r != MAILIMAP_NO_ERROR)
1668 return r;
1669
1670 r = mailimap_crlf_send(session->imap_stream);
1671 if (r != MAILIMAP_NO_ERROR)
1672 return r;
1673
1674 if (mailstream_flush(session->imap_stream) == -1)
1675 return MAILIMAP_ERROR_STREAM;
1676
1677 if (read_line(session) == NULL)
1678 return MAILIMAP_ERROR_STREAM;
1679
1680 if (session->imap_selection_info != NULL)
1681 mailimap_selection_info_free(session->imap_selection_info);
1682 session->imap_selection_info = mailimap_selection_info_new();
1683
1684 r = parse_response(session, &response);
1685 if (r != MAILIMAP_NO_ERROR)
1686 return r;
1687
1688 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1689
1690 mailimap_response_free(response);
1691
1692 switch (error_code) {
1693 case MAILIMAP_RESP_COND_STATE_OK:
1694 session->imap_state = MAILIMAP_STATE_SELECTED;
1695 return MAILIMAP_NO_ERROR;
1696
1697 default:
1698 mailimap_selection_info_free(session->imap_selection_info);
1699 session->imap_selection_info = NULL;
1700 session->imap_state = MAILIMAP_STATE_AUTHENTICATED;
1701 return MAILIMAP_ERROR_SELECT;
1702 }
1703}
1704
1705int
1706mailimap_status(mailimap * session, const char * mb,
1707 struct mailimap_status_att_list * status_att_list,
1708 struct mailimap_mailbox_data_status ** result)
1709{
1710 struct mailimap_response * response;
1711 int r;
1712 int error_code;
1713
1714 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1715 (session->imap_state != MAILIMAP_STATE_SELECTED))
1716 return MAILIMAP_ERROR_BAD_STATE;
1717
1718 r = send_current_tag(session);
1719 if (r != MAILIMAP_NO_ERROR)
1720 return r;
1721
1722 r = mailimap_status_send(session->imap_stream, mb, status_att_list);
1723 if (r != MAILIMAP_NO_ERROR)
1724 return r;
1725
1726 r = mailimap_crlf_send(session->imap_stream);
1727 if (r != MAILIMAP_NO_ERROR)
1728 return r;
1729
1730 if (mailstream_flush(session->imap_stream) == -1)
1731 return MAILIMAP_ERROR_STREAM;
1732
1733 if (read_line(session) == NULL)
1734 return MAILIMAP_ERROR_STREAM;
1735
1736 r = parse_response(session, &response);
1737 if (r != MAILIMAP_NO_ERROR)
1738 return r;
1739
1740 * result = session->imap_response_info->rsp_status;
1741 session->imap_response_info->rsp_status = NULL;
1742
1743 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1744
1745 mailimap_response_free(response);
1746
1747 switch (error_code) {
1748 case MAILIMAP_RESP_COND_STATE_OK:
1749 return MAILIMAP_NO_ERROR;
1750
1751 default:
1752 return MAILIMAP_ERROR_STATUS;
1753 }
1754}
1755
1756
1757int
1758mailimap_store(mailimap * session,
1759 struct mailimap_set * set,
1760 struct mailimap_store_att_flags * store_att_flags)
1761{
1762 struct mailimap_response * response;
1763 int r;
1764 int error_code;
1765
1766 if (session->imap_state != MAILIMAP_STATE_SELECTED)
1767 return MAILIMAP_ERROR_BAD_STATE;
1768
1769 r = send_current_tag(session);
1770 if (r != MAILIMAP_NO_ERROR)
1771 return r;
1772
1773 r = mailimap_store_send(session->imap_stream, set, store_att_flags);
1774 if (r != MAILIMAP_NO_ERROR)
1775 return r;
1776
1777 r = mailimap_crlf_send(session->imap_stream);
1778 if (r != MAILIMAP_NO_ERROR)
1779 return r;
1780
1781 if (mailstream_flush(session->imap_stream) == -1)
1782 return MAILIMAP_ERROR_STREAM;
1783
1784 if (read_line(session) == NULL)
1785 return MAILIMAP_ERROR_STREAM;
1786
1787 r = parse_response(session, &response);
1788 if (r != MAILIMAP_NO_ERROR)
1789 return r;
1790
1791 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1792
1793 mailimap_response_free(response);
1794
1795 switch (error_code) {
1796 case MAILIMAP_RESP_COND_STATE_OK:
1797 return MAILIMAP_NO_ERROR;
1798
1799 default:
1800 return MAILIMAP_ERROR_STORE;
1801 }
1802}
1803
1804int
1805mailimap_uid_store(mailimap * session,
1806 struct mailimap_set * set,
1807 struct mailimap_store_att_flags * store_att_flags)
1808{
1809 struct mailimap_response * response;
1810 int r;
1811 int error_code;
1812
1813 if (session->imap_state != MAILIMAP_STATE_SELECTED)
1814 return MAILIMAP_ERROR_BAD_STATE;
1815
1816 r = send_current_tag(session);
1817 if (r != MAILIMAP_NO_ERROR)
1818 return r;
1819
1820 r = mailimap_uid_store_send(session->imap_stream, set, store_att_flags);
1821 if (r != MAILIMAP_NO_ERROR)
1822 return r;
1823
1824 r = mailimap_crlf_send(session->imap_stream);
1825 if (r != MAILIMAP_NO_ERROR)
1826 return r;
1827
1828 if (mailstream_flush(session->imap_stream) == -1)
1829 return MAILIMAP_ERROR_STREAM;
1830
1831 if (read_line(session) == NULL)
1832 return MAILIMAP_ERROR_STREAM;
1833
1834 r = parse_response(session, &response);
1835 if (r != MAILIMAP_NO_ERROR)
1836 return r;
1837
1838 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1839
1840 mailimap_response_free(response);
1841
1842 switch (error_code) {
1843 case MAILIMAP_RESP_COND_STATE_OK:
1844 return MAILIMAP_NO_ERROR;
1845
1846 default:
1847 return MAILIMAP_ERROR_UID_STORE;
1848 }
1849}
1850
1851int mailimap_subscribe(mailimap * session, const char * mb)
1852{
1853 struct mailimap_response * response;
1854 int r;
1855 int error_code;
1856
1857 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1858 (session->imap_state != MAILIMAP_STATE_SELECTED))
1859 return MAILIMAP_ERROR_BAD_STATE;
1860
1861 r = send_current_tag(session);
1862 if (r != MAILIMAP_NO_ERROR)
1863 return r;
1864
1865 r = mailimap_subscribe_send(session->imap_stream, mb);
1866 if (r != MAILIMAP_NO_ERROR)
1867 return r;
1868
1869 r = mailimap_crlf_send(session->imap_stream);
1870 if (r != MAILIMAP_NO_ERROR)
1871 return r;
1872
1873 if (mailstream_flush(session->imap_stream) == -1)
1874 return MAILIMAP_ERROR_STREAM;
1875
1876 if (read_line(session) == NULL)
1877 return MAILIMAP_ERROR_STREAM;
1878
1879 r = parse_response(session, &response);
1880 if (r != MAILIMAP_NO_ERROR)
1881 return r;
1882
1883 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1884
1885 mailimap_response_free(response);
1886
1887 switch (error_code) {
1888 case MAILIMAP_RESP_COND_STATE_OK:
1889 return MAILIMAP_NO_ERROR;
1890
1891 default:
1892 return MAILIMAP_ERROR_SUBSCRIBE;
1893 }
1894}
1895
1896int mailimap_unsubscribe(mailimap * session, const char * mb)
1897{
1898 struct mailimap_response * response;
1899 int r;
1900 int error_code;
1901
1902 if ((session->imap_state != MAILIMAP_STATE_AUTHENTICATED) &&
1903 (session->imap_state != MAILIMAP_STATE_SELECTED))
1904 return MAILIMAP_ERROR_BAD_STATE;
1905
1906 r = send_current_tag(session);
1907 if (r != MAILIMAP_NO_ERROR)
1908 return r;
1909
1910 r = mailimap_subscribe_send(session->imap_stream, mb);
1911 if (r != MAILIMAP_NO_ERROR)
1912 return r;
1913
1914 r = mailimap_crlf_send(session->imap_stream);
1915 if (r != MAILIMAP_NO_ERROR)
1916 return r;
1917
1918 if (mailstream_flush(session->imap_stream) == -1)
1919 return MAILIMAP_ERROR_STREAM;
1920
1921 if (read_line(session) == NULL)
1922 return MAILIMAP_ERROR_STREAM;
1923
1924 r = parse_response(session, &response);
1925 if (r != MAILIMAP_NO_ERROR)
1926 return r;
1927
1928 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1929
1930 mailimap_response_free(response);
1931
1932 switch (error_code) {
1933 case MAILIMAP_RESP_COND_STATE_OK:
1934 return MAILIMAP_NO_ERROR;
1935
1936 default:
1937 return MAILIMAP_ERROR_UNSUBSCRIBE;
1938 }
1939}
1940
1941
1942int mailimap_starttls(mailimap * session)
1943{
1944 struct mailimap_response * response;
1945 int r;
1946 int error_code;
1947
1948 r = send_current_tag(session);
1949 if (r != MAILIMAP_NO_ERROR)
1950 return r;
1951
1952 r = mailimap_starttls_send(session->imap_stream);
1953 if (r != MAILIMAP_NO_ERROR)
1954 return r;
1955
1956 r = mailimap_crlf_send(session->imap_stream);
1957 if (r != MAILIMAP_NO_ERROR)
1958 return r;
1959
1960 if (mailstream_flush(session->imap_stream) == -1)
1961 return MAILIMAP_ERROR_STREAM;
1962
1963 if (read_line(session) == NULL)
1964 return MAILIMAP_ERROR_STREAM;
1965
1966 r = parse_response(session, &response);
1967 if (r != MAILIMAP_NO_ERROR)
1968 return r;
1969
1970 error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type;
1971
1972 mailimap_response_free(response);
1973
1974 switch (error_code) {
1975 case MAILIMAP_RESP_COND_STATE_OK:
1976 return MAILIMAP_NO_ERROR;
1977
1978 default:
1979 return MAILIMAP_ERROR_STARTTLS;
1980 }
1981}
1982
1983
1984
1985static char * read_line(mailimap * session)
1986{
1987 return mailstream_read_line(session->imap_stream, session->imap_stream_buffer);
1988}
1989
1990static int send_current_tag(mailimap * session)
1991{
1992 char tag_str[15];
1993 int r;
1994
1995 session->imap_tag ++;
1996 snprintf(tag_str, 15, "%i", session->imap_tag);
1997
1998 r = mailimap_tag_send(session->imap_stream, tag_str);
1999 if (r != MAILIMAP_NO_ERROR)
2000 return r;
2001
2002 r = mailimap_space_send(session->imap_stream);
2003 if (r != MAILIMAP_NO_ERROR)
2004 return r;
2005
2006 return MAILIMAP_NO_ERROR;
2007}
2008
2009static int parse_response(mailimap * session,
2010 struct mailimap_response ** result)
2011{
2012 size_t index;
2013 struct mailimap_response * response;
2014 char tag_str[15];
2015 int r;
2016
2017 index = 0;
2018
2019 session->imap_response = NULL;
2020
2021 r = mailimap_response_parse(session->imap_stream,
2022 session->imap_stream_buffer,
2023 &index, &response,
2024 session->imap_progr_rate, session->imap_progr_fun);
2025 if (r != MAILIMAP_NO_ERROR)
2026 return r;
2027
2028#if 0
2029 mailimap_response_print(response);
2030#endif
2031
2032 response_store(session, response);
2033
2034 if (mmap_string_assign(session->imap_response_buffer,
2035 response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_text->rsp_text)
2036 == NULL)
2037 return MAILIMAP_ERROR_MEMORY;
2038
2039 session->imap_response = session->imap_response_buffer->str;
2040
2041 if (response->rsp_resp_done->rsp_type == MAILIMAP_RESP_DONE_TYPE_FATAL)
2042 return MAILIMAP_ERROR_FATAL;
2043
2044 snprintf(tag_str, 15, "%i", session->imap_tag);
2045 if (strcmp(response->rsp_resp_done->rsp_data.rsp_tagged->rsp_tag, tag_str) != 0)
2046 return MAILIMAP_ERROR_PROTOCOL;
2047
2048 if (response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type ==
2049 MAILIMAP_RESP_COND_STATE_BAD)
2050 return MAILIMAP_ERROR_PROTOCOL;
2051
2052 * result = response;
2053
2054 return MAILIMAP_NO_ERROR;
2055}
2056
2057
2058static int parse_greeting(mailimap * session,
2059 struct mailimap_greeting ** result)
2060{
2061 size_t index;
2062 struct mailimap_greeting * greeting;
2063 int r;
2064
2065 index = 0;
2066
2067 session->imap_response = NULL;
2068
2069 r = mailimap_greeting_parse(session->imap_stream,
2070 session->imap_stream_buffer,
2071 &index, &greeting, session->imap_progr_rate,
2072 session->imap_progr_fun);
2073 if (r != MAILIMAP_NO_ERROR)
2074 return r;
2075
2076#if 0
2077 mailimap_greeting_print(greeting);
2078#endif
2079
2080 greeting_store(session, greeting);
2081
2082 if (greeting->gr_type == MAILIMAP_GREETING_RESP_COND_BYE) {
2083 if (mmap_string_assign(session->imap_response_buffer,
2084 greeting->gr_data.gr_bye->rsp_text->rsp_text) == NULL)
2085 return MAILIMAP_ERROR_MEMORY;
2086
2087 session->imap_response = session->imap_response_buffer->str;
2088
2089 return MAILIMAP_ERROR_DONT_ACCEPT_CONNECTION;
2090 }
2091
2092 if (mmap_string_assign(session->imap_response_buffer,
2093 greeting->gr_data.gr_auth->rsp_text->rsp_text) == NULL)
2094 return MAILIMAP_ERROR_MEMORY;
2095
2096 session->imap_response = session->imap_response_buffer->str;
2097
2098 * result = greeting;
2099
2100 return MAILIMAP_NO_ERROR;
2101}
2102
2103
2104mailimap * mailimap_new(size_t imap_progr_rate,
2105 progress_function * imap_progr_fun)
2106{
2107 mailimap * f;
2108
2109 f = malloc(sizeof(* f));
2110 if (f == NULL)
2111 goto err;
2112
2113 f->imap_response = NULL;
2114
2115 f->imap_stream = NULL;
2116
2117 f->imap_progr_rate = imap_progr_rate;
2118 f->imap_progr_fun = imap_progr_fun;
2119
2120 f->imap_stream_buffer = mmap_string_new("");
2121 if (f->imap_stream_buffer == NULL)
2122 goto free_f;
2123
2124 f->imap_response_buffer = mmap_string_new("");
2125 if (f->imap_response_buffer == NULL)
2126 goto free_stream_buffer;
2127
2128 f->imap_state = MAILIMAP_STATE_DISCONNECTED;
2129 f->imap_tag = 0;
2130
2131 f->imap_selection_info = NULL;
2132 f->imap_response_info = NULL;
2133 f->imap_connection_info = NULL;
2134
2135 return f;
2136
2137 free_stream_buffer:
2138 mmap_string_free(f->imap_stream_buffer);
2139 free_f:
2140 free(f);
2141 err:
2142 return NULL;
2143}
2144
2145void mailimap_free(mailimap * session)
2146{
2147 if (session->imap_stream)
2148 mailimap_logout(session);
2149
2150 mmap_string_free(session->imap_response_buffer);
2151 mmap_string_free(session->imap_stream_buffer);
2152
2153 if (session->imap_response_info)
2154 mailimap_response_info_free(session->imap_response_info);
2155 if (session->imap_selection_info)
2156 mailimap_selection_info_free(session->imap_selection_info);
2157 if (session->imap_connection_info)
2158 mailimap_connection_info_free(session->imap_connection_info);
2159
2160 free(session);
2161}
diff --git a/kmicromail/libetpan/imap/mailimap.h b/kmicromail/libetpan/imap/mailimap.h
new file mode 100644
index 0000000..8dfa3d4
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap.h
@@ -0,0 +1,598 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_H
37
38#define MAILIMAP_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailimap_types.h>
45#include <libetpan/mailimap_types_helper.h>
46#include <libetpan/mailimap_helper.h>
47
48#include <libetpan/mailimap_socket.h>
49#include <libetpan/mailimap_ssl.h>
50
51/*
52 mailimap_connect()
53
54 This function will connect the IMAP session with the given stream.
55
56 @param session the IMAP session
57 @param s stream to use
58
59 @return the return code is one of MAILIMAP_ERROR_XXX or
60 MAILIMAP_NO_ERROR codes
61
62 note that on success, MAILIMAP_NO_ERROR_AUTHENTICATED or
63 MAILIMAP_NO_ERROR_NON_AUTHENTICATED is returned
64
65 MAILIMAP_NO_ERROR_NON_AUTHENTICATED is returned when you need to
66 use mailimap_login() to authenticate, else
67 MAILIMAP_NO_ERROR_AUTHENTICATED is returned.
68*/
69
70int mailimap_connect(mailimap * session, mailstream * s);
71
72/*
73 mailimap_append()
74
75 This function will append a given message to the given mailbox
76 by sending an APPEND command.
77
78 @param session the IMAP session
79 @param mailbox name of the mailbox
80 @param flag_list flags of the message
81 @param date_time timestamp of the message
82 @param literal content of the message
83 @param literal_size size of the message
84
85 @return the return code is one of MAILIMAP_ERROR_XXX or
86 MAILIMAP_NO_ERROR codes
87*/
88
89int mailimap_append(mailimap * session, const char * mailbox,
90 struct mailimap_flag_list * flag_list,
91 struct mailimap_date_time * date_time,
92 const char * literal, size_t literal_size);
93
94/*
95 mailimap_noop()
96
97 This function will poll for an event on the server by
98 sending a NOOP command to the IMAP server
99
100 @param session IMAP session
101
102 @return the return code is one of MAILIMAP_ERROR_XXX or
103 MAILIMAP_NO_ERROR_XXX codes
104*/
105
106int mailimap_noop(mailimap * session);
107
108/*
109 mailimap_logout()
110
111 This function will logout from an IMAP server by sending
112 a LOGOUT command.
113
114 @param session IMAP session
115
116 @return the return code is one of MAILIMAP_ERROR_XXX or
117 MAILIMAP_NO_ERROR codes
118*/
119
120int mailimap_logout(mailimap * session);
121
122/*
123 mailimap_capability()
124
125 This function will query an IMAP server for his capabilities
126 by sending a CAPABILITY command.
127
128 @param session IMAP session
129 @param result The result of this command is a list of
130 capabilities and it is stored into (* result).
131
132 @return the return code is one of MAILIMAP_ERROR_XXX or
133 MAILIMAP_NO_ERROR codes
134 */
135
136int mailimap_capability(mailimap * session,
137 struct mailimap_capability_data ** result);
138
139/*
140 mailimap_check()
141
142 This function will request for a checkpoint of the mailbox by
143 sending a CHECK command.
144
145 @param session IMAP session
146
147 @return the return code is one of MAILIMAP_ERROR_XXX or
148 MAILIMAP_NO_ERROR codes
149 */
150
151int mailimap_check(mailimap * session);
152
153/*
154 mailimap_close()
155
156 This function will close the selected mailbox by sending
157 a CLOSE command.
158
159 @param session IMAP session
160
161 @return the return code is one of MAILIMAP_ERROR_XXX or
162 MAILIMAP_NO_ERROR codes
163 */
164
165int mailimap_close(mailimap * session);
166
167/*
168 mailimap_expunge()
169
170 This function will permanently remove from the selected mailbox
171 message that have the \Deleted flag set.
172
173 @param session IMAP session
174
175 @return the return code is one of MAILIMAP_ERROR_XXX or
176 MAILIMAP_NO_ERROR codes
177*/
178
179int mailimap_expunge(mailimap * session);
180
181/*
182 mailimap_copy()
183
184 This function will copy the given messages from the selected mailbox
185 to the given mailbox.
186
187 @param session IMAP session
188 @param set This is a set of message numbers.
189 @param mb This is the destination mailbox.
190
191 @return the return code is one of MAILIMAP_ERROR_XXX or
192 MAILIMAP_NO_ERROR codes
193 */
194
195int mailimap_copy(mailimap * session, struct mailimap_set * set,
196 const char * mb);
197
198/*
199 mailimap_uid_copy()
200
201 This function will copy the given messages from the selected mailbox
202 to the given mailbox.
203
204 @param session IMAP session
205 @param set This is a set of message unique identifiers.
206 @param mb This is the destination mailbox.
207
208 @return the return code is one of MAILIMAP_ERROR_XXX or
209 MAILIMAP_NO_ERROR codes
210 */
211
212int mailimap_uid_copy(mailimap * session,
213 struct mailimap_set * set, const char * mb);
214
215/*
216 mailimap_create()
217
218 This function will create a mailbox.
219
220 @param session IMAP session
221 @param mb This is the name of the mailbox to create.
222
223 @return the return code is one of MAILIMAP_ERROR_XXX or
224 MAILIMAP_NO_ERROR codes
225*/
226
227int mailimap_create(mailimap * session, const char * mb);
228
229/*
230 mailimap_delete()
231
232 This function will delete a mailox.
233
234 @param session IMAP session
235 @param mb This is the name of the mailbox to delete.
236
237 @return the return code is one of MAILIMAP_ERROR_XXX or
238 MAILIMAP_NO_ERROR codes
239*/
240
241int mailimap_delete(mailimap * session, const char * mb);
242
243/*
244 mailimap_examine()
245
246 This function will select the mailbox for read-only operations.
247
248 @param session IMAP session
249 @param mb This is the name of the mailbox to select.
250
251 @return the return code is one of MAILIMAP_ERROR_XXX or
252 MAILIMAP_NO_ERROR codes
253*/
254
255int mailimap_examine(mailimap * session, const char * mb);
256
257/*
258 mailimap_fetch()
259
260 This function will retrieve data associated with the given message
261 numbers.
262
263 @param session IMAP session
264 @param set set of message numbers
265 @param fetch_type type of information to be retrieved
266 @param result The result of this command is a clist
267 and it is stored into (* result). Each element of the clist is a
268 (struct mailimap_msg_att *).
269
270 @return the return code is one of MAILIMAP_ERROR_XXX or
271 MAILIMAP_NO_ERROR codes
272*/
273
274int
275mailimap_fetch(mailimap * session, struct mailimap_set * set,
276 struct mailimap_fetch_type * fetch_type, clist ** result);
277
278/*
279 mailimap_fetch()
280
281 This function will retrieve data associated with the given message
282 numbers.
283
284 @param session IMAP session
285 @param set set of message unique identifiers
286 @param fetch_type type of information to be retrieved
287 @param result The result of this command is a clist
288 and it is stored into (* result). Each element of the clist is a
289 (struct mailimap_msg_att *).
290
291 @return the return code is one of MAILIMAP_ERROR_XXX or
292 MAILIMAP_NO_ERROR codes
293*/
294
295int
296mailimap_uid_fetch(mailimap * session,
297 struct mailimap_set * set,
298 struct mailimap_fetch_type * fetch_type, clist ** result);
299
300/*
301 mailimap_fetch_list_free()
302
303 This function will free the result of a fetch command.
304
305 @param fetch_list This is the clist containing
306 (struct mailimap_msg_att *) elements to free.
307*/
308
309void mailimap_fetch_list_free(clist * fetch_list);
310
311/*
312 mailimap_list()
313
314 This function will return the list of the mailbox
315 available on the server.
316
317 @param session IMAP session
318 @param mb This is the reference name that informs
319 of the level of hierarchy
320 @param list_mb mailbox name with possible wildcard
321 @param result This will store a clist of (struct mailimap_mailbox_list *)
322 in (* result)
323
324 @return the return code is one of MAILIMAP_ERROR_XXX or
325 MAILIMAP_NO_ERROR codes
326*/
327
328int mailimap_list(mailimap * session, const char * mb,
329 const char * list_mb, clist ** result);
330
331/*
332 mailimap_login()
333
334 This function will authenticate the client.
335
336 @param session IMAP session
337 @param userid login of the user
338 @param password password of the user
339
340 @return the return code is one of MAILIMAP_ERROR_XXX or
341 MAILIMAP_NO_ERROR codes
342*/
343
344int mailimap_login(mailimap * session,
345 const char * userid, const char * password);
346
347/*
348 mailimap_lsub()
349
350 This function will return the list of the mailbox
351 that the client has subscribed to.
352
353 @param session IMAP session
354 @param mb This is the reference name that informs
355 of the level of hierarchy
356 @param list_mb mailbox name with possible wildcard
357 @param result This will store a list of (struct mailimap_mailbox_list *)
358 in (* result)
359
360 @return the return code is one of MAILIMAP_ERROR_XXX or
361 MAILIMAP_NO_ERROR codes
362*/
363
364int mailimap_lsub(mailimap * session, const char * mb,
365 const char * list_mb, clist ** result);
366
367/*
368 mailimap_list_result_free()
369
370 This function will free the clist of (struct mailimap_mailbox_list *)
371
372 @param list This is the clist to free.
373*/
374
375void mailimap_list_result_free(clist * list);
376
377/*
378 mailimap_rename()
379
380 This function will change the name of a mailbox.
381
382 @param session IMAP session
383 @param mb current name
384 @param new_name new name
385
386 @return the return code is one of MAILIMAP_ERROR_XXX or
387 MAILIMAP_NO_ERROR codes
388*/
389
390int mailimap_rename(mailimap * session,
391 const char * mb, const char * new_name);
392
393/*
394 mailimap_search()
395
396 All mails that match the given criteria will be returned
397 their numbers in the result list.
398
399 @param session IMAP session
400 @param charset This indicates the charset of the strings that appears
401 in the searching criteria
402 @param key This is the searching criteria
403 @param result The result is a clist of (uint32_t *) and will be
404 stored in (* result).
405
406 @return the return code is one of MAILIMAP_ERROR_XXX or
407 MAILIMAP_NO_ERROR codes
408*/
409
410int
411mailimap_search(mailimap * session, const char * charset,
412 struct mailimap_search_key * key, clist ** result);
413
414/*
415 mailimap_uid_search()
416
417
418 All mails that match the given criteria will be returned
419 their unique identifiers in the result list.
420
421 @param session IMAP session
422 @param charset This indicates the charset of the strings that appears
423 in the searching criteria
424 @param key This is the searching criteria
425 @param result The result is a clist of (uint32_t *) and will be
426 stored in (* result).
427
428 @return the return code is one of MAILIMAP_ERROR_XXX or
429 MAILIMAP_NO_ERROR codes
430*/
431
432int
433mailimap_uid_search(mailimap * session, const char * charset,
434 struct mailimap_search_key * key, clist ** result);
435
436/*
437 mailimap_search_result_free()
438
439 This function will free the result of the a search.
440
441 @param search_result This is a clist of (uint32_t *) returned
442 by mailimap_uid_search() or mailimap_search()
443*/
444
445void mailimap_search_result_free(clist * search_result);
446
447/*
448 mailimap_select()
449
450 This function will select a given mailbox so that messages in the
451 mailbox can be accessed.
452
453 @param session IMAP session
454 @param mb This is the name of the mailbox to select.
455
456 @return the return code is one of MAILIMAP_ERROR_XXX or
457 MAILIMAP_NO_ERROR codes
458*/
459
460int
461mailimap_select(mailimap * session, const char * mb);
462
463/*
464 mailimap_status()
465
466 This function will return informations about a given mailbox.
467
468 @param session IMAP session
469 @param mb This is the name of the mailbox
470 @param status_att_list This is the list of mailbox information to return
471 @param result List of returned values
472
473 @return the return code is one of MAILIMAP_ERROR_XXX or
474 MAILIMAP_NO_ERROR codes
475*/
476
477int
478mailimap_status(mailimap * session, const char * mb,
479 struct mailimap_status_att_list * status_att_list,
480 struct mailimap_mailbox_data_status ** result);
481
482/*
483 mailimap_uid_store()
484
485 This function will alter the data associated with some messages
486 (flags of the messages).
487
488 @param session IMAP session
489 @param set This is a list of message numbers.
490 @param store_att_flags This is the data to associate with the
491 given messages
492
493 @return the return code is one of MAILIMAP_ERROR_XXX or
494 MAILIMAP_NO_ERROR codes
495*/
496
497int
498mailimap_store(mailimap * session,
499 struct mailimap_set * set,
500 struct mailimap_store_att_flags * store_att_flags);
501
502/*
503 mailimap_uid_store()
504
505 This function will alter the data associated with some messages
506 (flags of the messages).
507
508 @param session IMAP session
509 @param set This is a list of message unique identifiers.
510 @param store_att_flags This is the data to associate with the
511 given messages
512
513 @return the return code is one of MAILIMAP_ERROR_XXX or
514 MAILIMAP_NO_ERROR codes
515*/
516
517int
518mailimap_uid_store(mailimap * session,
519 struct mailimap_set * set,
520 struct mailimap_store_att_flags * store_att_flags);
521
522/*
523 mailimap_subscribe()
524
525 This function adds the specified mailbox name to the
526 server's set of "active" or "subscribed" mailboxes.
527
528 @param session IMAP session
529 @param mb This is the name of the mailbox
530
531 @return the return code is one of MAILIMAP_ERROR_XXX or
532 MAILIMAP_NO_ERROR codes
533*/
534
535int mailimap_subscribe(mailimap * session, const char * mb);
536
537/*
538 mailimap_unsubscribe()
539
540 This function removes the specified mailbox name to the
541 server's set of "active" or "subscribed" mailboxes.
542
543 @param session IMAP session
544 @param mb This is the name of the mailbox
545
546 @return the return code is one of MAILIMAP_ERROR_XXX or
547 MAILIMAP_NO_ERROR codes
548*/
549
550int mailimap_unsubscribe(mailimap * session, const char * mb);
551
552/*
553 mailimap_starttls()
554
555 This function starts change the mode of the connection to
556 switch to SSL connection.
557
558 @param session IMAP session
559
560 @return the return code is one of MAILIMAP_ERROR_XXX or
561 MAILIMAP_NO_ERROR_XXX codes
562 */
563
564int mailimap_starttls(mailimap * session);
565
566/*
567 mailimap_new()
568
569 This function returns a new IMAP session.
570
571 @param progr_rate When downloading messages, a function will be called
572 each time the amount of bytes downloaded reaches a multiple of this
573 value, this can be 0.
574 @param progr_fun This is the function to call to notify the progress,
575 this can be NULL.
576
577 @return an IMAP session is returned.
578 */
579
580mailimap * mailimap_new(size_t imap_progr_rate,
581 progress_function * imap_progr_fun);
582
583/*
584 mailimap_free()
585
586 This function will free the data structures associated with
587 the IMAP session.
588
589 @param session IMAP session
590 */
591
592void mailimap_free(mailimap * session);
593
594#ifdef __cplusplus
595}
596#endif
597
598#endif
diff --git a/kmicromail/libetpan/imap/mailimap_helper.c b/kmicromail/libetpan/imap/mailimap_helper.c
new file mode 100644
index 0000000..afc9098
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_helper.c
@@ -0,0 +1,205 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimap_helper.h"
37
38#include <stdlib.h>
39#include "mailimap.h"
40
41int mailimap_fetch_rfc822(mailimap * session,
42 uint32_t msgid, char ** result)
43{
44 int r;
45 clist * fetch_list;
46 struct mailimap_fetch_att * fetch_att;
47 struct mailimap_fetch_type * fetch_type;
48 struct mailimap_set * set;
49 struct mailimap_msg_att * msg_att;
50 struct mailimap_msg_att_item * item;
51 int res;
52
53 fetch_att = mailimap_fetch_att_new_rfc822();
54 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
55 set = mailimap_set_new_single(msgid);
56
57 r = mailimap_fetch(session, set, fetch_type, &fetch_list);
58
59 mailimap_set_free(set);
60 mailimap_fetch_type_free(fetch_type);
61
62 if (r != MAILIMAP_NO_ERROR) {
63 res = r;
64 goto err;
65 }
66
67 if (clist_isempty(fetch_list)) {
68 res = MAILIMAP_ERROR_FETCH;
69 goto free;
70 }
71
72 msg_att = (struct mailimap_msg_att *) clist_begin(fetch_list)->data;
73
74 if (clist_isempty(msg_att->att_list)) {
75 res = MAILIMAP_ERROR_FETCH;
76 goto free;
77 }
78
79 item = (struct mailimap_msg_att_item *) clist_begin(msg_att->att_list)->data;
80
81 if (item->att_type != MAILIMAP_MSG_ATT_ITEM_STATIC) {
82 res = MAILIMAP_ERROR_FETCH;
83 goto free;
84 }
85 if (item->att_data.att_static->att_type != MAILIMAP_MSG_ATT_RFC822) {
86 res = MAILIMAP_ERROR_FETCH;
87 goto free;
88 }
89
90 * result = item->att_data.att_static->att_data.att_rfc822.att_content;
91 item->att_data.att_static->att_data.att_rfc822.att_content = NULL;
92 mailimap_fetch_list_free(fetch_list);
93
94 return MAILIMAP_NO_ERROR;
95
96free:
97 mailimap_fetch_list_free(fetch_list);
98err:
99 return res;
100}
101
102int mailimap_fetch_rfc822_header(mailimap * session,
103 uint32_t msgid, char ** result)
104{
105 int r;
106 int res;
107 clist * fetch_list;
108 struct mailimap_fetch_att * fetch_att;
109 struct mailimap_fetch_type * fetch_type;
110 struct mailimap_set * set;
111 struct mailimap_msg_att * msg_att;
112 struct mailimap_msg_att_item * item;
113
114 fetch_att = mailimap_fetch_att_new_rfc822_header();
115 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
116 set = mailimap_set_new_single(msgid);
117
118 r = mailimap_fetch(session, set, fetch_type, &fetch_list);
119
120 mailimap_set_free(set);
121 mailimap_fetch_type_free(fetch_type);
122
123 if (r != MAILIMAP_NO_ERROR) {
124 res = r;
125 goto err;
126 }
127
128 if (clist_isempty(fetch_list)) {
129 res = MAILIMAP_ERROR_FETCH;
130 goto free;
131 }
132
133 msg_att = (struct mailimap_msg_att *) clist_begin(fetch_list)->data;
134
135 if (clist_isempty(msg_att->att_list)) {
136 res = MAILIMAP_ERROR_FETCH;
137 goto free;
138 }
139
140 item = (struct mailimap_msg_att_item *) clist_begin(msg_att->att_list)->data;
141
142 if (item->att_type != MAILIMAP_MSG_ATT_ITEM_STATIC) {
143 res = MAILIMAP_ERROR_FETCH;
144 goto err;
145 }
146
147 if (item->att_data.att_static->att_type != MAILIMAP_MSG_ATT_RFC822_HEADER) {
148 res = MAILIMAP_ERROR_FETCH;
149 goto err;
150 }
151
152 * result = item->att_data.att_static->att_data.att_rfc822_header.att_content;
153 item->att_data.att_static->att_data.att_rfc822_header.att_content = NULL;
154 mailimap_fetch_list_free(fetch_list);
155
156 return MAILIMAP_NO_ERROR;
157
158free:
159 mailimap_fetch_list_free(fetch_list);
160err:
161 return res;
162}
163
164int mailimap_fetch_envelope(mailimap * session,
165 uint32_t first, uint32_t last,
166 clist ** result)
167{
168 int r;
169 clist * fetch_list;
170 struct mailimap_fetch_att * fetch_att;
171 struct mailimap_fetch_type * fetch_type;
172 struct mailimap_set * set;
173
174 fetch_att = mailimap_fetch_att_new_envelope();
175 fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att);
176 set = mailimap_set_new_interval(first, last);
177
178 r = mailimap_fetch(session, set, fetch_type, &fetch_list);
179
180 mailimap_set_free(set);
181 mailimap_fetch_type_free(fetch_type);
182
183 if (r != MAILIMAP_NO_ERROR)
184 return r;
185
186 * result = fetch_list;
187
188 return MAILIMAP_NO_ERROR;
189}
190
191int mailimap_append_simple(mailimap * session, char * mailbox,
192 char * content, uint32_t size)
193{
194 return mailimap_append(session, mailbox, NULL, NULL, content, size);
195}
196
197int mailimap_login_simple(mailimap * session,
198 char * userid, char * password)
199{
200 if (session->imap_state == MAILIMAP_STATE_NON_AUTHENTICATED)
201 return mailimap_login(session, userid, password);
202 else
203 return MAILIMAP_NO_ERROR;
204}
205
diff --git a/kmicromail/libetpan/imap/mailimap_helper.h b/kmicromail/libetpan/imap/mailimap_helper.h
new file mode 100644
index 0000000..d73cf5f
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_helper.h
@@ -0,0 +1,66 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_HELPER_H
37
38#define MAILIMAP_HELPER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailimap_types.h>
45
46int mailimap_fetch_rfc822(mailimap * session,
47 uint32_t msgid, char ** result);
48
49int mailimap_fetch_rfc822_header(mailimap * session,
50 uint32_t msgid, char ** result);
51
52int mailimap_fetch_envelope(mailimap * session,
53 uint32_t first, uint32_t last,
54 clist ** result);
55
56int mailimap_append_simple(mailimap * session, char * mailbox,
57 char * content, uint32_t size);
58
59int mailimap_login_simple(mailimap * session,
60 char * userid, char * password);
61
62#ifdef __cplusplus
63}
64#endif
65
66#endif
diff --git a/kmicromail/libetpan/imap/mailimap_keywords.c b/kmicromail/libetpan/imap/mailimap_keywords.c
new file mode 100644
index 0000000..b277aed
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_keywords.c
@@ -0,0 +1,353 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimap_keywords.h"
37#include "mailimap_types.h"
38#include <string.h>
39#include <stdio.h>
40
41#ifndef UNSTRICT_SYNTAX
42#define UNSTRICT_SYNTAX
43#endif
44
45struct mailimap_token_value {
46 int value;
47 const char * str;
48};
49
50int mailimap_token_case_insensitive_parse(mailstream * fd,
51 MMAPString * buffer,
52 size_t * index,
53 const char * token)
54{
55 int len;
56 int cur_token;
57 int r;
58
59 cur_token = * index;
60 len = strlen(token);
61
62#ifdef UNSTRICT_SYNTAX
63 r = mailimap_space_parse(fd, buffer, &cur_token);
64 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
65 return r;
66#endif
67
68 if (strncasecmp(buffer->str + cur_token, token, len) == 0) {
69 cur_token += len;
70 * index = cur_token;
71 return MAILIMAP_NO_ERROR;
72 }
73 else
74 return MAILIMAP_ERROR_PARSE;
75}
76
77
78static int is_space_or_tab(char ch)
79{
80 return (ch == ' ') || (ch == '\t');
81}
82
83int mailimap_char_parse(mailstream * fd, MMAPString * buffer,
84 size_t * index, char token)
85{
86 int cur_token;
87
88 cur_token = * index;
89
90 if (buffer->str[cur_token] == token) {
91 cur_token ++;
92 * index = cur_token;
93 return MAILIMAP_NO_ERROR;
94 }
95 else
96 return MAILIMAP_ERROR_PARSE;
97}
98
99int mailimap_space_parse(mailstream * fd, MMAPString * buffer,
100 size_t * index)
101{
102#ifdef UNSTRICT_SYNTAX
103
104 /* can accept unstrict syntax */
105 size_t cur_token;
106
107 cur_token = * index;
108
109 while (is_space_or_tab(* (buffer->str + cur_token)))
110 cur_token ++;
111
112 if (cur_token == * index)
113 return MAILIMAP_ERROR_PARSE;
114
115 * index = cur_token;
116
117 return MAILIMAP_NO_ERROR;
118
119#else
120 return mailimap_char_parse(fd, buffer, index, ' ');
121#endif
122}
123
124
125
126#define mailimap_get_token_str(index, tab) \
127 mailimap_get_token_str_size(index, tab, \
128 sizeof(tab) / sizeof(struct mailimap_token_value))
129
130#define mailimap_get_token_value(fd, buffer, index, tab) \
131 mailimap_get_token_value_size(fd, buffer, index, tab, \
132 sizeof(tab) / sizeof(struct mailimap_token_value))
133
134
135static const char * mailimap_get_token_str_size(int index,
136 struct mailimap_token_value * tab,
137 size_t size)
138{
139 size_t i;
140
141 for(i = 0 ; i < size ; i++)
142 if (index == tab[i].value)
143 return tab[i].str;
144
145 return NULL;
146}
147
148
149
150static int mailimap_get_token_value_size(mailstream * fd, MMAPString * buffer,
151 size_t * index,
152 struct mailimap_token_value * tab,
153 size_t size)
154{
155 size_t i;
156 int r;
157
158#ifdef UNSTRICT_SYNTAX
159 /* can accept unstrict syntax */
160 r = mailimap_space_parse(fd, buffer, index);
161 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
162 return r;
163#endif
164
165 for(i = 0 ; i < size ; i++) {
166 r = mailimap_token_case_insensitive_parse(fd, buffer, index, tab[i].str);
167 if (r == MAILIMAP_NO_ERROR)
168 return tab[i].value;
169 }
170
171 return -1;
172}
173
174
175static struct mailimap_token_value status_att_tab[] = {
176 {MAILIMAP_STATUS_ATT_MESSAGES, "MESSAGES"},
177 {MAILIMAP_STATUS_ATT_RECENT, "RECENT"},
178 {MAILIMAP_STATUS_ATT_UIDNEXT, "UIDNEXT"},
179 {MAILIMAP_STATUS_ATT_UIDVALIDITY, "UIDVALIDITY"},
180 {MAILIMAP_STATUS_ATT_UNSEEN, "UNSEEN"}
181};
182
183int mailimap_status_att_get_token_value(mailstream * fd, MMAPString * buffer,
184 size_t * index)
185{
186 int r;
187
188#ifdef UNSTRICT_SYNTAX
189 /* can accept unstrict syntax */
190 r = mailimap_space_parse(fd, buffer, index);
191 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
192 return r;
193#endif
194 return mailimap_get_token_value(fd, buffer, index,
195 status_att_tab);
196}
197
198
199const char * mailimap_status_att_get_token_str(size_t index)
200{
201 return mailimap_get_token_str(index, status_att_tab);
202}
203
204static struct mailimap_token_value month_tab[] = {
205 {1, "Jan"},
206 {2, "Feb"},
207 {3, "Mar"},
208 {4, "Apr"},
209 {5, "May"},
210 {6, "Jun"},
211 {7, "Jul"},
212 {8, "Aug"},
213 {9, "Sep"},
214 {10, "Oct"},
215 {11, "Nov"},
216 {12, "Dec"}
217};
218
219int mailimap_month_get_token_value(mailstream * fd, MMAPString * buffer,
220 size_t * index)
221{
222 return mailimap_get_token_value(fd, buffer, index, month_tab);
223}
224
225
226const char * mailimap_month_get_token_str(size_t index)
227{
228 return mailimap_get_token_str(index, month_tab);
229}
230
231
232
233
234
235static struct mailimap_token_value mailimap_flag_tab[] = {
236 {MAILIMAP_FLAG_ANSWERED, "\\Answered"},
237 {MAILIMAP_FLAG_FLAGGED, "\\Flagged"},
238 {MAILIMAP_FLAG_DELETED, "\\Deleted"},
239 {MAILIMAP_FLAG_SEEN, "\\Seen"},
240 {MAILIMAP_FLAG_DRAFT, "\\Draft"}
241};
242
243int mailimap_flag_get_token_value(mailstream * fd, MMAPString * buffer,
244 size_t * index)
245{
246 return mailimap_get_token_value(fd, buffer, index,
247 mailimap_flag_tab);
248}
249
250
251const char * mailimap_flag_get_token_str(size_t index)
252{
253 return mailimap_get_token_str(index, mailimap_flag_tab);
254}
255
256
257
258
259static struct mailimap_token_value encoding_tab[] = {
260 {MAILIMAP_BODY_FLD_ENC_7BIT, "7BIT"},
261 {MAILIMAP_BODY_FLD_ENC_8BIT, "8BIT"},
262 {MAILIMAP_BODY_FLD_ENC_BINARY, "BINARY"},
263 {MAILIMAP_BODY_FLD_ENC_BASE64, "BASE64"},
264 {MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE, "QUOTED-PRINTABLE"}
265};
266
267int mailimap_encoding_get_token_value(mailstream * fd, MMAPString * buffer,
268 size_t * index)
269{
270 return mailimap_get_token_value(fd, buffer, index, encoding_tab);
271}
272
273static struct mailimap_token_value mbx_list_sflag_tab[] = {
274 {MAILIMAP_MBX_LIST_SFLAG_MARKED, "\\Marked"},
275 {MAILIMAP_MBX_LIST_SFLAG_NOSELECT, "\\Noselect"},
276 {MAILIMAP_MBX_LIST_SFLAG_UNMARKED, "\\Unmarked"}
277};
278
279int mailimap_mbx_list_sflag_get_token_value(mailstream * fd,
280 MMAPString * buffer,
281 size_t * index)
282{
283 return mailimap_get_token_value(fd, buffer, index, mbx_list_sflag_tab);
284}
285
286static struct mailimap_token_value media_basic_tab[] = {
287 {MAILIMAP_MEDIA_BASIC_APPLICATION, "APPLICATION"},
288 {MAILIMAP_MEDIA_BASIC_AUDIO, "AUDIO"},
289 {MAILIMAP_MEDIA_BASIC_IMAGE, "IMAGE"},
290 {MAILIMAP_MEDIA_BASIC_MESSAGE, "MESSAGE"},
291 {MAILIMAP_MEDIA_BASIC_VIDEO, "VIDEO"}
292};
293
294int mailimap_media_basic_get_token_value(mailstream * fd, MMAPString * buffer,
295 size_t * index)
296{
297 return mailimap_get_token_value(fd, buffer, index, media_basic_tab);
298}
299
300static struct mailimap_token_value resp_cond_state_tab[] = {
301 {MAILIMAP_RESP_COND_STATE_OK, "OK"},
302 {MAILIMAP_RESP_COND_STATE_NO, "NO"},
303 {MAILIMAP_RESP_COND_STATE_BAD, "BAD"}
304};
305
306int mailimap_resp_cond_state_get_token_value(mailstream * fd,
307 MMAPString * buffer,
308 size_t * index)
309{
310 return mailimap_get_token_value(fd, buffer, index, resp_cond_state_tab);
311}
312
313static struct mailimap_token_value resp_text_code_1_tab[] = {
314 {MAILIMAP_RESP_TEXT_CODE_ALERT, "ALERT"},
315 {MAILIMAP_RESP_TEXT_CODE_PARSE, "PARSE"},
316 {MAILIMAP_RESP_TEXT_CODE_READ_ONLY, "READ-ONLY"},
317 {MAILIMAP_RESP_TEXT_CODE_READ_WRITE, "READ-WRITE"},
318 {MAILIMAP_RESP_TEXT_CODE_TRY_CREATE, "TRYCREATE"}
319};
320
321int mailimap_resp_text_code_1_get_token_value(mailstream * fd,
322 MMAPString * buffer,
323 size_t * index)
324{
325 return mailimap_get_token_value(fd, buffer, index, resp_text_code_1_tab);
326}
327
328static struct mailimap_token_value resp_text_code_2_tab[] = {
329 {MAILIMAP_RESP_TEXT_CODE_UIDNEXT, "UIDNEXT"},
330 {MAILIMAP_RESP_TEXT_CODE_UIDVALIDITY, "UIDVALIDITY"},
331 {MAILIMAP_RESP_TEXT_CODE_UNSEEN, "UNSEEN"},
332};
333
334int mailimap_resp_text_code_2_get_token_value(mailstream * fd,
335 MMAPString * buffer,
336 size_t * index)
337{
338 return mailimap_get_token_value(fd, buffer, index, resp_text_code_2_tab);
339}
340
341static struct mailimap_token_value section_msgtext_tab[] = {
342 {MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT, "HEADER.FIELDS.NOT"},
343 {MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS, "HEADER.FIELDS"},
344 {MAILIMAP_SECTION_MSGTEXT_HEADER, "HEADER"},
345 {MAILIMAP_SECTION_MSGTEXT_TEXT, "TEXT"}
346};
347
348int mailimap_section_msgtext_get_token_value(mailstream * fd,
349 MMAPString * buffer,
350 size_t * index)
351{
352 return mailimap_get_token_value(fd, buffer, index, section_msgtext_tab);
353}
diff --git a/kmicromail/libetpan/imap/mailimap_keywords.h b/kmicromail/libetpan/imap/mailimap_keywords.h
new file mode 100644
index 0000000..a8443aa
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_keywords.h
@@ -0,0 +1,107 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_COMMON_H
37
38#define MAILIMAP_COMMON_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mailstream.h"
45
46
47/* tools */
48
49int mailimap_char_parse(mailstream * fd, MMAPString * buffer,
50 size_t * index, char token);
51
52int mailimap_space_parse(mailstream * fd, MMAPString * buffer,
53 size_t * index);
54
55/* tokens */
56
57int mailimap_token_case_insensitive_parse(mailstream * fd,
58 MMAPString * buffer,
59 size_t * index,
60 const char * token);
61
62int mailimap_status_att_get_token_value(mailstream * fd, MMAPString * buffer,
63 size_t * index);
64const char * mailimap_status_att_get_token_str(size_t index);
65
66
67int mailimap_month_get_token_value(mailstream * fd, MMAPString * buffer,
68 size_t * index);
69const char * mailimap_month_get_token_str(size_t index);
70
71
72int mailimap_flag_get_token_value(mailstream * fd, MMAPString * buffer,
73 size_t * index);
74
75const char * mailimap_flag_get_token_str(size_t index);
76
77int mailimap_encoding_get_token_value(mailstream * fd, MMAPString * buffer,
78 size_t * index);
79
80int mailimap_mbx_list_sflag_get_token_value(mailstream * fd,
81 MMAPString * buffer,
82 size_t * index);
83
84int mailimap_media_basic_get_token_value(mailstream * fd, MMAPString * buffer,
85 size_t * index);
86
87int mailimap_resp_cond_state_get_token_value(mailstream * fd,
88 MMAPString * buffer,
89 size_t * index);
90
91int mailimap_resp_text_code_1_get_token_value(mailstream * fd,
92 MMAPString * buffer,
93 size_t * index);
94
95int mailimap_resp_text_code_2_get_token_value(mailstream * fd,
96 MMAPString * buffer,
97 size_t * index);
98
99int mailimap_section_msgtext_get_token_value(mailstream * fd,
100 MMAPString * buffer,
101 size_t * index);
102
103#ifdef __cplusplus
104}
105#endif
106
107#endif
diff --git a/kmicromail/libetpan/imap/mailimap_parser.c b/kmicromail/libetpan/imap/mailimap_parser.c
new file mode 100644
index 0000000..1c2ecde
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_parser.c
@@ -0,0 +1,9506 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include <string.h>
37#include <stdlib.h>
38#include <stdio.h>
39
40#include "mailstream.h"
41#include "mailimap_keywords.h"
42#include "mailimap_parser.h"
43#include "mmapstring.h"
44#include "mail.h"
45
46#ifndef UNSTRICT_SYNTAX
47#define UNSTRICT_SYNTAX
48#endif
49
50/*
51 Document: internet-drafts/draft-crispin-imapv-15.txt
52 RFC 2060 (IMAP but rather used draft)
53 RFC 2234 for all token that are not defined such as ALPHA
54*/
55
56
57
58/* ************************************************************************* */
59/* ************************************************************************* */
60/* ************************************************************************* */
61/* ************************************************************************* */
62/* ************************************************************************* */
63/* ************************************************************************* */
64
65
66
67
68static int mailimap_address_parse(mailstream * fd, MMAPString * buffer,
69 size_t * index,
70 struct mailimap_address ** result,
71 size_t progr_rate,
72 progress_function * progr_fun);
73
74static int mailimap_addr_adl_parse(mailstream * fd, MMAPString * buffer,
75 size_t * index, char ** result,
76 size_t progr_rate,
77 progress_function * progr_fun);
78
79static int mailimap_addr_host_parse(mailstream * fd, MMAPString * buffer,
80 size_t * index, char ** result,
81 size_t progr_rate,
82 progress_function * progr_fun);
83
84static int mailimap_addr_mailbox_parse(mailstream * fd, MMAPString * buffer,
85 size_t * index, char ** result,
86 size_t progr_rate,
87 progress_function * progr_fun);
88
89static int mailimap_addr_name_parse(mailstream * fd, MMAPString * buffer,
90 size_t * index, char ** result,
91 size_t progr_rate,
92 progress_function * progr_fun);
93
94
95static int
96mailimap_astring_parse(mailstream * fd, MMAPString * buffer,
97 size_t * index,
98 char ** result,
99 size_t progr_rate,
100 progress_function * progr_fun);
101
102static int mailimap_atom_parse(mailstream * fd, MMAPString * buffer,
103 size_t * index, char ** result,
104 size_t progr_rate,
105 progress_function * progr_fun);
106
107static int mailimap_auth_type_parse(mailstream * fd, MMAPString * buffer,
108 size_t * index, char ** result,
109 size_t progr_rate,
110 progress_function * progr_fun);
111
112static int mailimap_base64_parse(mailstream * fd, MMAPString * buffer,
113 size_t * index, char ** result,
114 size_t progr_rate,
115 progress_function * progr_fun);
116
117static int mailimap_body_parse(mailstream * fd, MMAPString * buffer,
118 size_t * index,
119 struct mailimap_body ** result,
120 size_t progr_rate,
121 progress_function * progr_fun);
122
123
124static int
125mailimap_body_extension_parse(mailstream * fd, MMAPString * buffer,
126 size_t * index,
127 struct mailimap_body_extension ** result,
128 size_t progr_rate,
129 progress_function * progr_fun);
130
131
132static int
133mailimap_body_ext_1part_parse(mailstream * fd, MMAPString * buffer,
134 size_t * index,
135 struct mailimap_body_ext_1part ** result,
136 size_t progr_rate,
137 progress_function * progr_fun);
138
139
140
141static int
142mailimap_body_ext_mpart_parse(mailstream * fd, MMAPString * buffer,
143 size_t * index,
144 struct mailimap_body_ext_mpart ** result,
145 size_t progr_rate,
146 progress_function * progr_fun);
147
148
149static int
150mailimap_body_fields_parse(mailstream * fd, MMAPString * buffer,
151 size_t * index,
152 struct mailimap_body_fields ** result,
153 size_t progr_rate,
154 progress_function * progr_fun);
155
156static int mailimap_body_fld_desc_parse(mailstream * fd, MMAPString * buffer,
157 size_t * index, char ** result,
158 size_t progr_rate,
159 progress_function * progr_fun);
160
161
162static int
163mailimap_body_fld_dsp_parse(mailstream * fd, MMAPString * buffer,
164 size_t * index,
165 struct mailimap_body_fld_dsp ** result,
166 size_t progr_rate,
167 progress_function * progr_fun);
168
169
170
171static int
172mailimap_body_fld_enc_parse(mailstream * fd, MMAPString * buffer,
173 size_t * index,
174 struct mailimap_body_fld_enc ** result,
175 size_t progr_rate,
176 progress_function * progr_fun);
177
178
179
180static int mailimap_body_fld_id_parse(mailstream * fd, MMAPString * buffer,
181 size_t * index, char ** result,
182 size_t progr_rate,
183 progress_function * progr_fun);
184
185
186static int
187mailimap_body_fld_lang_parse(mailstream * fd, MMAPString * buffer,
188 size_t * index,
189 struct mailimap_body_fld_lang ** result,
190 size_t progr_rate,
191 progress_function * progr_fun);
192
193static int mailimap_body_fld_lines_parse(mailstream * fd,
194 MMAPString * buffer, size_t * index,
195 uint32_t * result);
196
197static int mailimap_body_fld_md5_parse(mailstream * fd, MMAPString * buffer,
198 size_t * index, char ** result,
199 size_t progr_rate,
200 progress_function * progr_fun);
201
202static int mailimap_body_fld_octets_parse(mailstream * fd,
203 MMAPString * buffer, size_t * index,
204 uint32_t * result);
205
206static int
207mailimap_body_fld_param_parse(mailstream * fd,
208 MMAPString * buffer, size_t * index,
209 struct mailimap_body_fld_param ** result,
210 size_t progr_rate,
211 progress_function * progr_fun);
212
213
214
215static int
216mailimap_body_type_1part_parse(mailstream * fd, MMAPString * buffer,
217 size_t * index,
218 struct mailimap_body_type_1part ** result,
219 size_t progr_rate,
220 progress_function * progr_fun);
221
222
223
224static int
225mailimap_body_type_basic_parse(mailstream * fd, MMAPString * buffer,
226 size_t * index,
227 struct mailimap_body_type_basic ** result,
228 size_t progr_rate,
229 progress_function * progr_fun);
230
231
232
233static int
234mailimap_body_type_mpart_parse(mailstream * fd,
235 MMAPString * buffer,
236 size_t * index,
237 struct mailimap_body_type_mpart ** result,
238 size_t progr_rate,
239 progress_function * progr_fun);
240
241
242
243static int
244mailimap_body_type_msg_parse(mailstream * fd, MMAPString * buffer,
245 size_t * index,
246 struct mailimap_body_type_msg ** result,
247 size_t progr_rate,
248 progress_function * progr_fun);
249
250
251
252static int
253mailimap_body_type_text_parse(mailstream * fd, MMAPString * buffer,
254 size_t * index,
255 struct mailimap_body_type_text **
256 result,
257 size_t progr_rate,
258 progress_function * progr_fun);
259
260
261
262static int
263mailimap_capability_parse(mailstream * fd, MMAPString * buffer,
264 size_t * index,
265 struct mailimap_capability ** result,
266 size_t progr_rate,
267 progress_function * progr_fun);
268
269
270
271static int
272mailimap_capability_data_parse(mailstream * fd, MMAPString * buffer,
273 size_t * index,
274 struct mailimap_capability_data ** result,
275 size_t progr_rate,
276 progress_function * progr_fun);
277
278
279/*
280static gboolean mailimap_date_day_parse(mailstream * fd,
281 MMAPString * buffer,
282 guint32 * index,
283 gint * result);
284*/
285static int mailimap_date_day_fixed_parse(mailstream * fd,
286 MMAPString * buffer,
287 size_t * index,
288 int * result);
289
290static int mailimap_date_month_parse(mailstream * fd, MMAPString * buffer,
291 size_t * index, int * result);
292
293/*
294struct mailimap_date_text {
295 gint day;
296 gint month;
297 gint year;
298};
299
300static gboolean
301mailimap_date_text_parse(mailstream * fd, MMAPString * buffer,
302 guint32 * index, struct mailimap_date_text ** result);
303static void mailimap_date_text_free(struct mailimap_date_text * date_text);
304*/
305
306static int mailimap_date_year_parse(mailstream * fd, MMAPString * buffer,
307 size_t * index, int * result);
308
309static int mailimap_date_time_parse(mailstream * fd, MMAPString * buffer,
310 size_t * index,
311 struct mailimap_date_time ** t,
312 size_t progr_rate,
313 progress_function * progr_fun);
314
315#ifndef UNSTRICT_SYNTAX
316static int mailimap_digit_nz_parse(mailstream * fd, MMAPString * buffer,
317 size_t * index, int * result);
318#endif
319
320
321static int mailimap_envelope_parse(mailstream * fd, MMAPString * buffer,
322 size_t * index,
323 struct mailimap_envelope ** result,
324 size_t progr_rate,
325 progress_function * progr_fun);
326
327
328static int
329mailimap_env_bcc_parse(mailstream * fd, MMAPString * buffer,
330 size_t * index, struct mailimap_env_bcc ** result,
331 size_t progr_rate,
332 progress_function * progr_fun);
333
334
335static int
336mailimap_env_cc_parse(mailstream * fd, MMAPString * buffer,
337 size_t * index, struct mailimap_env_cc ** result,
338 size_t progr_rate,
339 progress_function * progr_fun);
340
341static int mailimap_env_date_parse(mailstream * fd, MMAPString * buffer,
342 size_t * index, char ** result,
343 size_t progr_rate,
344 progress_function * progr_fun);
345
346
347static int
348mailimap_env_from_parse(mailstream * fd, MMAPString * buffer,
349 size_t * index, struct mailimap_env_from ** result,
350 size_t progr_rate,
351 progress_function * progr_fun);
352
353
354static int mailimap_env_in_reply_to_parse(mailstream * fd,
355 MMAPString * buffer,
356 size_t * index, char ** result,
357 size_t progr_rate,
358 progress_function * progr_fun);
359
360static int mailimap_env_message_id_parse(mailstream * fd,
361 MMAPString * buffer,
362 size_t * index, char ** result,
363 size_t progr_rate,
364 progress_function * progr_fun);
365
366static int
367mailimap_env_reply_to_parse(mailstream * fd, MMAPString * buffer,
368 size_t * index,
369 struct mailimap_env_reply_to ** result,
370 size_t progr_rate,
371 progress_function * progr_fun);
372
373
374
375static int
376mailimap_env_sender_parse(mailstream * fd, MMAPString * buffer,
377 size_t * index, struct mailimap_env_sender ** result,
378 size_t progr_rate,
379 progress_function * progr_fun);
380
381static int mailimap_env_subject_parse(mailstream * fd, MMAPString * buffer,
382 size_t * index, char ** result,
383 size_t progr_rate,
384 progress_function * progr_fun);
385
386
387static int
388mailimap_env_to_parse(mailstream * fd, MMAPString * buffer,
389 size_t * index,
390 struct mailimap_env_to ** result,
391 size_t progr_rate,
392 progress_function * progr_fun);
393
394
395static int mailimap_flag_parse(mailstream * fd, MMAPString * buffer,
396 size_t * index,
397 struct mailimap_flag ** result,
398 size_t progr_rate,
399 progress_function * progr_fun);
400
401static int mailimap_flag_extension_parse(mailstream * fd,
402 MMAPString * buffer,
403 size_t * index,
404 char ** result,
405 size_t progr_rate,
406 progress_function * progr_fun);
407
408
409
410
411static int
412mailimap_flag_fetch_parse(mailstream * fd, MMAPString * buffer,
413 size_t * index,
414 struct mailimap_flag_fetch ** result,
415 size_t progr_rate,
416 progress_function * progr_fun);
417
418
419
420static int
421mailimap_flag_perm_parse(mailstream * fd, MMAPString * buffer,
422 size_t * index,
423 struct mailimap_flag_perm ** result,
424 size_t progr_rate,
425 progress_function * progr_fun);
426
427
428static int mailimap_flag_keyword_parse(mailstream * fd, MMAPString * buffer,
429 size_t * index,
430 char ** result,
431 size_t progr_rate,
432 progress_function * progr_fun);
433
434
435static int mailimap_flag_list_parse(mailstream * fd, MMAPString * buffer,
436 size_t * index,
437 struct mailimap_flag_list ** result,
438 size_t progr_rate,
439 progress_function * progr_fun);
440
441
442static int
443mailimap_header_fld_name_parse(mailstream * fd,
444 MMAPString * buffer,
445 size_t * index,
446 char ** result,
447 size_t progr_rate,
448 progress_function * progr_fun);
449
450
451
452
453static int
454mailimap_header_list_parse(mailstream * fd, MMAPString * buffer,
455 size_t * index,
456 struct mailimap_header_list ** result,
457 size_t progr_rate,
458 progress_function * progr_fun);
459
460static int mailimap_literal_parse(mailstream * fd, MMAPString * buffer,
461 size_t * index, char ** result,
462 size_t * result_len,
463 size_t progr_rate,
464 progress_function * progr_fun);
465
466
467static int
468mailimap_mailbox_parse(mailstream * fd, MMAPString * buffer,
469 size_t * index, char ** result,
470 size_t progr_rate,
471 progress_function * progr_fun);
472
473
474
475
476static int
477mailimap_mailbox_data_parse(mailstream * fd, MMAPString * buffer,
478 size_t * index,
479 struct mailimap_mailbox_data ** result,
480 size_t progr_rate,
481 progress_function * progr_fun);
482
483
484static int
485mailimap_mbx_list_flags_parse(mailstream * fd, MMAPString * buffer,
486 size_t * index,
487 struct mailimap_mbx_list_flags ** result,
488 size_t progr_rate,
489 progress_function * progr_fun);
490
491
492static int
493mailimap_mbx_list_oflag_parse(mailstream * fd, MMAPString * buffer,
494 size_t * index,
495 struct mailimap_mbx_list_oflag ** result,
496 size_t progr_rate,
497 progress_function * progr_fun);
498
499static int
500mailimap_mbx_list_oflag_no_sflag_parse(mailstream * fd, MMAPString * buffer,
501 size_t * index,
502 struct mailimap_mbx_list_oflag ** result,
503 size_t progr_rate,
504 progress_function * progr_fun);
505
506static int
507mailimap_mbx_list_sflag_parse(mailstream * fd, MMAPString * buffer,
508 size_t * index,
509 int * result);
510
511
512static int
513mailimap_mailbox_list_parse(mailstream * fd, MMAPString * buffer,
514 size_t * index,
515 struct mailimap_mailbox_list ** result,
516 size_t progr_rate,
517 progress_function * progr_fun);
518
519
520
521static int
522mailimap_media_basic_parse(mailstream * fd, MMAPString * buffer,
523 size_t * index,
524 struct mailimap_media_basic ** result,
525 size_t progr_rate,
526 progress_function * progr_fun);
527
528static int
529mailimap_media_message_parse(mailstream * fd, MMAPString * buffer,
530 size_t * index);
531
532static int
533mailimap_media_subtype_parse(mailstream * fd, MMAPString * buffer,
534 size_t * index,
535 char ** result,
536 size_t progr_rate,
537 progress_function * progr_fun);
538
539static int mailimap_media_text_parse(mailstream * fd, MMAPString * buffer,
540 size_t * index,
541 char ** result,
542 size_t progr_rate,
543 progress_function * progr_fun);
544
545
546
547static int
548mailimap_message_data_parse(mailstream * fd, MMAPString * buffer,
549 size_t * index,
550 struct mailimap_message_data ** result,
551 size_t progr_rate,
552 progress_function * progr_fun);
553
554
555
556
557
558static int
559mailimap_msg_att_parse(mailstream * fd, MMAPString * buffer,
560 size_t * index, struct mailimap_msg_att ** result,
561 size_t progr_rate,
562 progress_function * progr_fun);
563
564
565
566static int
567mailimap_msg_att_dynamic_parse(mailstream * fd, MMAPString * buffer,
568 size_t * index,
569 struct mailimap_msg_att_dynamic ** result,
570 size_t progr_rate,
571 progress_function * progr_fun);
572
573
574static int
575mailimap_msg_att_static_parse(mailstream * fd, MMAPString * buffer,
576 size_t * index,
577 struct mailimap_msg_att_static ** result,
578 size_t progr_rate,
579 progress_function * progr_fun);
580
581static int mailimap_nil_parse(mailstream * fd, MMAPString * buffer,
582 size_t * index);
583
584static int mailimap_nstring_parse(mailstream * fd, MMAPString * buffer,
585 size_t * index, char ** result,
586 size_t * result_len,
587 size_t progr_rate,
588 progress_function * progr_fun);
589
590static int
591mailimap_number_parse(mailstream * fd, MMAPString * buffer,
592 size_t * index, uint32_t * result);
593
594static int
595mailimap_nz_number_parse(mailstream * fd, MMAPString * buffer,
596 size_t * index, uint32_t * result);
597
598
599static int
600mailimap_quoted_parse(mailstream * fd, MMAPString * buffer,
601 size_t * index, char ** result,
602 size_t progr_rate,
603 progress_function * progr_fun);
604
605static int
606mailimap_quoted_char_parse(mailstream * fd, MMAPString * buffer,
607 size_t * index, char * result);
608
609
610static int
611mailimap_quoted_specials_parse(mailstream * fd, MMAPString * buffer,
612 size_t * index, char * result);
613
614
615
616
617
618static int
619mailimap_response_data_parse(mailstream * fd, MMAPString * buffer,
620 size_t * index,
621 struct mailimap_response_data ** result,
622 size_t progr_rate,
623 progress_function * progr_fun);
624
625
626
627
628static int
629mailimap_response_done_parse(mailstream * fd, MMAPString * buffer,
630 size_t * index,
631 struct mailimap_response_done ** result,
632 size_t progr_rate,
633 progress_function * progr_fun);
634
635static int
636mailimap_response_fatal_parse(mailstream * fd, MMAPString * buffer,
637 size_t * index,
638 struct mailimap_response_fatal ** result,
639 size_t progr_rate,
640 progress_function * progr_fun);
641
642
643static int
644mailimap_response_tagged_parse(mailstream * fd, MMAPString * buffer,
645 size_t * index,
646 struct mailimap_response_tagged ** result,
647 size_t progr_rate,
648 progress_function * progr_fun);
649
650
651static int
652mailimap_resp_cond_auth_parse(mailstream * fd, MMAPString * buffer,
653 size_t * index,
654 struct mailimap_resp_cond_auth ** result,
655 size_t progr_rate,
656 progress_function * progr_fun);
657
658static int
659mailimap_resp_cond_bye_parse(mailstream * fd, MMAPString * buffer,
660 size_t * index,
661 struct mailimap_resp_cond_bye ** result,
662 size_t progr_rate,
663 progress_function * progr_fun);
664
665
666static int
667mailimap_resp_cond_state_parse(mailstream * fd, MMAPString * buffer,
668 size_t * index,
669 struct mailimap_resp_cond_state ** result,
670 size_t progr_rate,
671 progress_function * progr_fun);
672
673
674static int
675mailimap_resp_text_parse(mailstream * fd, MMAPString * buffer,
676 size_t * index,
677 struct mailimap_resp_text ** result,
678 size_t progr_rate,
679 progress_function * progr_fun);
680
681
682static int
683mailimap_resp_text_code_parse(mailstream * fd, MMAPString * buffer,
684 size_t * index,
685 struct mailimap_resp_text_code ** result,
686 size_t progr_rate,
687 progress_function * progr_fun);
688
689
690static int
691mailimap_section_parse(mailstream * fd, MMAPString * buffer,
692 size_t * index,
693 struct mailimap_section ** result,
694 size_t progr_rate,
695 progress_function * progr_fun);
696
697
698static int
699mailimap_section_msgtext_parse(mailstream * fd, MMAPString * buffer,
700 size_t * index,
701 struct mailimap_section_msgtext ** result,
702 size_t progr_rate,
703 progress_function * progr_fun);
704
705
706static int
707mailimap_section_part_parse(mailstream * fd, MMAPString * buffer,
708 size_t * index,
709 struct mailimap_section_part ** result,
710 size_t progr_rate,
711 progress_function * progr_fun);
712
713
714
715
716static int
717mailimap_section_spec_parse(mailstream * fd, MMAPString * buffer,
718 size_t * index,
719 struct mailimap_section_spec ** result,
720 size_t progr_rate,
721 progress_function * progr_fun);
722
723
724static int
725mailimap_section_text_parse(mailstream * fd, MMAPString * buffer,
726 size_t * index,
727 struct mailimap_section_text ** result,
728 size_t progr_rate,
729 progress_function * progr_fun);
730
731
732static int mailimap_status_att_parse(mailstream * fd, MMAPString * buffer,
733 size_t * index, int * result);
734
735static int
736mailimap_string_parse(mailstream * fd, MMAPString * buffer,
737 size_t * index, char ** result,
738 size_t * result_len,
739 size_t progr_rate,
740 progress_function * progr_fun);
741
742static int mailimap_tag_parse(mailstream * fd, MMAPString * buffer,
743 size_t * index, char ** result,
744 size_t progr_rate,
745 progress_function * progr_fun);
746
747static int mailimap_text_parse(mailstream * fd, MMAPString * buffer,
748 size_t * index, char ** result,
749 size_t progr_rate,
750 progress_function * progr_fun);
751
752static int mailimap_time_parse(mailstream * fd, MMAPString * buffer,
753 size_t * index,
754 int * phour, int * pmin, int * psec);
755
756static int mailimap_uniqueid_parse(mailstream * fd, MMAPString * buffer,
757 size_t * index, uint32_t * result);
758
759static int mailimap_zone_parse(mailstream * fd, MMAPString * buffer,
760 size_t * index, int * result);
761
762
763
764/* ************************************************************************* */
765/* ************************************************************************* */
766/* ************************************************************************* */
767/* ************************************************************************* */
768/* ************************************************************************* */
769/* ************************************************************************* */
770
771
772
773
774
775/* ******************** TOOLS **************************** */
776
777
778static int mailimap_unstrict_char_parse(mailstream * fd, MMAPString * buffer,
779 size_t * index, char token)
780{
781 size_t cur_token;
782 int r;
783
784 cur_token = * index;
785
786#ifdef UNSTRICT_SYNTAX
787 /* can accept unstrict syntax */
788
789 mailimap_space_parse(fd, buffer, &cur_token);
790 if (token == ' ') {
791 * index = cur_token;
792 return MAILIMAP_NO_ERROR;
793 }
794#endif
795
796 r = mailimap_char_parse(fd, buffer, &cur_token, token);
797 if (r != MAILIMAP_NO_ERROR)
798 return r;
799
800 * index = cur_token;
801
802 return MAILIMAP_NO_ERROR;
803}
804
805static int mailimap_oparenth_parse(mailstream * fd, MMAPString * buffer,
806 size_t * index)
807{
808 return mailimap_unstrict_char_parse(fd, buffer, index, '(');
809}
810
811static int mailimap_cparenth_parse(mailstream * fd, MMAPString * buffer,
812 size_t * index)
813{
814 return mailimap_unstrict_char_parse(fd, buffer, index, ')');
815}
816
817static int mailimap_oaccolade_parse(mailstream * fd, MMAPString * buffer,
818 size_t * index)
819{
820 return mailimap_unstrict_char_parse(fd, buffer, index, '{');
821}
822
823static int mailimap_caccolade_parse(mailstream * fd, MMAPString * buffer,
824 size_t * index)
825{
826 return mailimap_unstrict_char_parse(fd, buffer, index, '}');
827}
828
829static int mailimap_plus_parse(mailstream * fd, MMAPString * buffer,
830 size_t * index)
831{
832 return mailimap_unstrict_char_parse(fd, buffer, index, '+');
833}
834
835static int mailimap_minus_parse(mailstream * fd, MMAPString * buffer,
836 size_t * index)
837{
838 return mailimap_unstrict_char_parse(fd, buffer, index, '-');
839}
840
841static int mailimap_star_parse(mailstream * fd, MMAPString * buffer,
842 size_t * index)
843{
844 return mailimap_unstrict_char_parse(fd, buffer, index, '*');
845}
846
847static int mailimap_dot_parse(mailstream * fd, MMAPString * buffer,
848 size_t * index)
849{
850 return mailimap_unstrict_char_parse(fd, buffer, index, '.');
851}
852
853static int mailimap_colon_parse(mailstream * fd, MMAPString * buffer,
854 size_t * index)
855{
856 return mailimap_unstrict_char_parse(fd, buffer, index, ':');
857}
858
859static int mailimap_lower_parse(mailstream * fd, MMAPString * buffer,
860 size_t * index)
861{
862 return mailimap_unstrict_char_parse(fd, buffer, index, '<');
863}
864
865static int mailimap_greater_parse(mailstream * fd, MMAPString * buffer,
866 size_t * index)
867{
868 return mailimap_unstrict_char_parse(fd, buffer, index, '>');
869}
870
871static int mailimap_obracket_parse(mailstream * fd, MMAPString * buffer,
872 size_t * index)
873{
874 return mailimap_unstrict_char_parse(fd, buffer, index, '[');
875}
876
877static int mailimap_cbracket_parse(mailstream * fd, MMAPString * buffer,
878 size_t * index)
879{
880 return mailimap_unstrict_char_parse(fd, buffer, index, ']');
881}
882
883static int mailimap_dquote_parse(mailstream * fd, MMAPString * buffer,
884 size_t * index)
885{
886 return mailimap_char_parse(fd, buffer, index, '\"');
887}
888
889static int mailimap_crlf_parse(mailstream * fd, MMAPString * buffer,
890 size_t * index)
891{
892 size_t cur_token = * index;
893
894#ifdef UNSTRICT_SYNTAX
895 mailimap_space_parse(fd, buffer, &cur_token);
896#endif
897
898 if (mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "\r\n")) {
899 * index = cur_token;
900 return MAILIMAP_NO_ERROR;
901 }
902
903#ifdef UNSTRICT_SYNTAX
904 else if (mailimap_unstrict_char_parse(fd, buffer, &cur_token, '\n')) {
905 * index = cur_token;
906 return MAILIMAP_NO_ERROR;
907 }
908#endif
909
910 else
911 return MAILIMAP_ERROR_PARSE;
912}
913
914typedef int mailimap_struct_parser(mailstream * fd, MMAPString * buffer,
915 size_t * index, void * result,
916 size_t progr_rate,
917 progress_function * progr_fun);
918typedef int mailimap_struct_destructor(void * result);
919
920
921static int
922mailimap_struct_multiple_parse(mailstream * fd, MMAPString * buffer,
923 size_t * index, clist ** result,
924 mailimap_struct_parser * parser,
925 mailimap_struct_destructor * destructor,
926 size_t progr_rate,
927 progress_function * progr_fun)
928{
929 clist * struct_list;
930 size_t cur_token;
931 void * value;
932 int r;
933 int res;
934
935 cur_token = * index;
936
937 r = parser(fd, buffer, &cur_token, &value, progr_rate, progr_fun);
938 if (r != MAILIMAP_NO_ERROR) {
939 res = r;
940 goto err;
941 }
942
943 struct_list = clist_new();
944 if (struct_list == NULL) {
945 destructor(value);
946 res = MAILIMAP_ERROR_MEMORY;
947 goto err;
948 }
949
950 r = clist_append(struct_list, value);
951 if (r < 0) {
952 destructor(value);
953 res = MAILIMAP_ERROR_MEMORY;
954 goto free_list;
955 }
956
957 while (1) {
958 r = parser(fd, buffer, &cur_token, &value, progr_rate, progr_fun);
959 if (r == MAILIMAP_ERROR_PARSE)
960 break;
961 if (r != MAILIMAP_NO_ERROR) {
962 res = r;
963 goto free_list;
964 }
965
966 r = clist_append(struct_list, value);
967 if (r < 0) {
968 destructor(value);
969 res = MAILIMAP_ERROR_MEMORY;
970 goto free_list;
971 }
972 }
973
974 * result = struct_list;
975 * index = cur_token;
976
977 return MAILIMAP_NO_ERROR;
978
979 free_list:
980 clist_foreach(struct_list, (clist_func) destructor, NULL);
981 clist_free(struct_list);
982 err:
983 return res;
984}
985
986static int
987mailimap_struct_list_parse(mailstream * fd, MMAPString * buffer,
988 size_t * index, clist ** result,
989 char symbol,
990 mailimap_struct_parser * parser,
991 mailimap_struct_destructor * destructor,
992 size_t progr_rate,
993 progress_function * progr_fun)
994{
995 clist * struct_list;
996 size_t cur_token;
997 void * value;
998 size_t final_token;
999 int r;
1000 int res;
1001
1002 cur_token = * index;
1003 struct_list = NULL;
1004
1005 r = parser(fd, buffer, &cur_token, &value, progr_rate, progr_fun);
1006 if (r != MAILIMAP_NO_ERROR) {
1007 res = r;
1008 goto err;
1009 }
1010
1011 struct_list = clist_new();
1012 if (struct_list == NULL) {
1013 destructor(value);
1014 res = MAILIMAP_ERROR_MEMORY;
1015 goto err;
1016 }
1017
1018 r = clist_append(struct_list, value);
1019 if (r < 0) {
1020 destructor(value);
1021 res = MAILIMAP_ERROR_MEMORY;
1022 goto free_list;
1023 }
1024
1025 final_token = cur_token;
1026
1027 while (1) {
1028 r = mailimap_unstrict_char_parse(fd, buffer, &cur_token, symbol);
1029 if (r == MAILIMAP_ERROR_PARSE)
1030 break;
1031 if (r != MAILIMAP_NO_ERROR) {
1032 res = r;
1033 goto free_list;
1034 }
1035
1036 r = parser(fd, buffer, &cur_token, &value, progr_rate, progr_fun);
1037 if (r == MAILIMAP_ERROR_PARSE)
1038 break;
1039
1040 if (r != MAILIMAP_NO_ERROR) {
1041 res = r;
1042 goto free_list;
1043 }
1044
1045 r = clist_append(struct_list, value);
1046 if (r < 0) {
1047 destructor(value);
1048 res = MAILIMAP_ERROR_MEMORY;
1049 goto free_list;
1050 }
1051
1052 final_token = cur_token;
1053 }
1054
1055 * result = struct_list;
1056 * index = final_token;
1057
1058 return MAILIMAP_NO_ERROR;
1059
1060 free_list:
1061 clist_foreach(struct_list, (clist_func) destructor, NULL);
1062 clist_free(struct_list);
1063 err:
1064 return res;
1065}
1066
1067static int
1068mailimap_struct_spaced_list_parse(mailstream * fd, MMAPString * buffer,
1069 size_t * index, clist ** result,
1070 mailimap_struct_parser * parser,
1071 mailimap_struct_destructor * destructor,
1072 size_t progr_rate,
1073 progress_function * progr_fun)
1074{
1075 return mailimap_struct_list_parse(fd, buffer, index, result,
1076 ' ', parser, destructor,
1077 progr_rate, progr_fun);
1078}
1079
1080
1081
1082static int
1083mailimap_custom_string_parse(mailstream * fd, MMAPString * buffer,
1084 size_t * index, char ** result,
1085 int (* is_custom_char)(char))
1086{
1087 size_t begin;
1088 size_t end;
1089 char * gstr;
1090
1091 begin = * index;
1092
1093#ifdef UNSTRICT_SYNTAX
1094 mailimap_space_parse(fd, buffer, &begin);
1095#endif
1096
1097 end = begin;
1098
1099 while (is_custom_char(buffer->str[end]))
1100 end ++;
1101
1102 if (end != begin) {
1103 gstr = malloc(end - begin + 1);
1104 if (gstr == NULL)
1105 return MAILIMAP_ERROR_MEMORY;
1106
1107 strncpy(gstr, buffer->str + begin, end - begin);
1108 gstr[end - begin] = '\0';
1109
1110 * index = end;
1111 * result = gstr;
1112 return MAILIMAP_NO_ERROR;
1113 }
1114 else
1115 return MAILIMAP_ERROR_PARSE;
1116}
1117
1118
1119
1120static int
1121mailimap_nz_number_alloc_parse(mailstream * fd, MMAPString * buffer,
1122 size_t * index,
1123 uint32_t ** result,
1124 size_t progr_rate,
1125 progress_function * progr_fun)
1126{
1127 uint32_t number;
1128 uint32_t * number_alloc;
1129 size_t cur_token;
1130 int r;
1131
1132 cur_token = * index;
1133
1134 r = mailimap_nz_number_parse(fd, buffer, &cur_token, &number);
1135 if (r != MAILIMAP_NO_ERROR)
1136 return r;
1137
1138 number_alloc = mailimap_number_alloc_new(number);
1139 if (number_alloc == NULL)
1140 return MAILIMAP_ERROR_MEMORY;
1141
1142 * index = cur_token;
1143 * result = number_alloc;
1144
1145 return MAILIMAP_NO_ERROR;
1146}
1147
1148
1149static int is_ctl(char ch)
1150{
1151 unsigned char uch = (unsigned char) ch;
1152
1153 return (uch <= 0x1F);
1154}
1155
1156static int is_char(char ch)
1157{
1158#ifdef UNSTRICT_SYNTAX
1159 return (ch != 0);
1160#else
1161 unsigned char uch = ch;
1162
1163 return (uch >= 0x01) && (uch <= 0x7f);
1164#endif
1165}
1166
1167static int is_alpha(char ch)
1168{
1169 return ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && (ch <= 'z')));
1170}
1171
1172static int is_digit(char ch)
1173{
1174 return (ch >= '0') && (ch <= '9');
1175}
1176
1177static int mailimap_digit_parse(mailstream * fd, MMAPString * buffer,
1178 size_t * index, int * result)
1179{
1180 size_t cur_token;
1181
1182 cur_token = * index;
1183
1184 if (is_digit(buffer->str[cur_token])) {
1185 * result = buffer->str[cur_token] - '0';
1186 cur_token ++;
1187 * index = cur_token;
1188 return MAILIMAP_NO_ERROR;
1189 }
1190 else
1191 return MAILIMAP_ERROR_PARSE;
1192}
1193
1194
1195/* ******************** parser **************************** */
1196
1197/*
1198 address = "(" addr-name SP addr-adl SP addr-mailbox SP
1199 addr-host ")"
1200*/
1201
1202static int mailimap_address_parse(mailstream * fd, MMAPString * buffer,
1203 size_t * index,
1204 struct mailimap_address ** result,
1205 size_t progr_rate,
1206 progress_function * progr_fun)
1207{
1208 size_t cur_token;
1209 char * addr_name;
1210 char * addr_adl;
1211 char * addr_mailbox;
1212 char * addr_host;
1213 struct mailimap_address * addr;
1214 int r;
1215 int res;
1216
1217 cur_token = * index;
1218
1219 addr_name = NULL;
1220 addr_adl = NULL;
1221 addr_mailbox = NULL;
1222 addr_host = NULL;
1223
1224 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
1225 if (r != MAILIMAP_NO_ERROR) {
1226 res = r;
1227 goto err;
1228 }
1229
1230 r = mailimap_addr_name_parse(fd, buffer, &cur_token, &addr_name,
1231 progr_rate, progr_fun);
1232 if (r != MAILIMAP_NO_ERROR) {
1233 res = r;
1234 goto err;
1235 }
1236
1237 r = mailimap_space_parse(fd, buffer, &cur_token);
1238 if (r != MAILIMAP_NO_ERROR) {
1239 res = r;
1240 goto addr_name_free;
1241 }
1242
1243 r = mailimap_addr_adl_parse(fd, buffer, &cur_token, &addr_adl,
1244 progr_rate, progr_fun);
1245 if (r != MAILIMAP_NO_ERROR) {
1246 res = r;
1247 goto addr_name_free;
1248 }
1249
1250 r = mailimap_space_parse(fd, buffer, &cur_token);
1251 if (r != MAILIMAP_NO_ERROR) {
1252 res = r;
1253 goto addr_adl_free;
1254 }
1255
1256 r = mailimap_addr_mailbox_parse(fd, buffer, &cur_token, &addr_mailbox,
1257 progr_rate, progr_fun);
1258 if (r != MAILIMAP_NO_ERROR) {
1259 res = r;
1260 goto addr_adl_free;
1261 }
1262
1263 r = mailimap_space_parse(fd, buffer, &cur_token);
1264 if (r != MAILIMAP_NO_ERROR) {
1265 res = r;
1266 goto addr_mailbox_free;
1267 }
1268
1269 r = mailimap_addr_host_parse(fd, buffer, &cur_token, &addr_host,
1270 progr_rate, progr_fun);
1271 if (r != MAILIMAP_NO_ERROR) {
1272 res = r;
1273 goto addr_mailbox_free;
1274 }
1275
1276 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
1277 if (r != MAILIMAP_NO_ERROR) {
1278 res = r;
1279 goto addr_host_free;
1280 }
1281
1282 addr = mailimap_address_new(addr_name, addr_adl, addr_mailbox, addr_host);
1283
1284 if (addr == NULL) {
1285 res = MAILIMAP_ERROR_MEMORY;
1286 goto addr_host_free;
1287 }
1288
1289 * result = addr;
1290 * index = cur_token;
1291
1292 return MAILIMAP_NO_ERROR;
1293
1294 addr_host_free:
1295 mailimap_addr_host_free(addr_host);
1296 addr_mailbox_free:
1297 mailimap_addr_mailbox_free(addr_mailbox);
1298 addr_adl_free:
1299 mailimap_addr_adl_free(addr_adl);
1300 addr_name_free:
1301 mailimap_addr_name_free(addr_name);
1302 err:
1303 return res;
1304}
1305
1306/*
1307 addr-adl = nstring
1308 ; Holds route from [RFC-822] route-addr if
1309 ; non-NIL
1310*/
1311
1312static int mailimap_addr_adl_parse(mailstream * fd, MMAPString * buffer,
1313 size_t * index, char ** result,
1314 size_t progr_rate,
1315 progress_function * progr_fun)
1316{
1317 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
1318 progr_rate, progr_fun);
1319}
1320
1321/*
1322 addr-host = nstring
1323 ; NIL indicates [RFC-822] group syntax.
1324 ; Otherwise, holds [RFC-822] domain name
1325*/
1326
1327static int mailimap_addr_host_parse(mailstream * fd, MMAPString * buffer,
1328 size_t * index, char ** result,
1329 size_t progr_rate,
1330 progress_function * progr_fun)
1331{
1332 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
1333 progr_rate, progr_fun);
1334}
1335
1336/*
1337 addr-mailbox = nstring
1338 ; NIL indicates end of [RFC-822] group; if
1339 ; non-NIL and addr-host is NIL, holds
1340 ; [RFC-822] group name.
1341 ; Otherwise, holds [RFC-822] local-part
1342 ; after removing [RFC-822] quoting
1343 */
1344
1345static int mailimap_addr_mailbox_parse(mailstream * fd, MMAPString * buffer,
1346 size_t * index, char ** result,
1347 size_t progr_rate,
1348 progress_function * progr_fun)
1349{
1350 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
1351 progr_rate, progr_fun);
1352}
1353
1354
1355/*
1356 addr-name = nstring
1357 ; If non-NIL, holds phrase from [RFC-822]
1358 ; mailbox after removing [RFC-822] quoting
1359*/
1360
1361static int mailimap_addr_name_parse(mailstream * fd, MMAPString * buffer,
1362 size_t * index, char ** result,
1363 size_t progr_rate,
1364 progress_function * progr_fun)
1365{
1366 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
1367 progr_rate, progr_fun);
1368}
1369
1370
1371/*
1372 NOT IMPLEMENTED
1373 append = "APPEND" SP mailbox [SP flag-list] [SP date-time] SP
1374 literal
1375*/
1376
1377/*
1378 astring = 1*ASTRING-CHAR / string
1379*/
1380
1381static int is_astring_char(char ch);
1382
1383static int
1384mailimap_atom_astring_parse(mailstream * fd, MMAPString * buffer,
1385 size_t * index, char ** result,
1386 size_t progr_rate,
1387 progress_function * progr_fun)
1388{
1389 return mailimap_custom_string_parse(fd, buffer, index, result,
1390 is_astring_char);
1391}
1392
1393static int
1394mailimap_astring_parse(mailstream * fd, MMAPString * buffer,
1395 size_t * index,
1396 char ** result,
1397 size_t progr_rate,
1398 progress_function * progr_fun)
1399{
1400 size_t cur_token;
1401 char * astring;
1402 int r;
1403
1404 cur_token = * index;
1405
1406 r = mailimap_atom_astring_parse(fd, buffer, &cur_token, &astring,
1407 progr_rate, progr_fun);
1408 switch (r) {
1409 case MAILIMAP_NO_ERROR:
1410 break;
1411
1412 case MAILIMAP_ERROR_PARSE:
1413 r = mailimap_string_parse(fd, buffer, &cur_token, &astring, NULL,
1414 progr_rate, progr_fun);
1415 if (r != MAILIMAP_NO_ERROR)
1416 return r;
1417 break;
1418
1419 default:
1420 return r;
1421 }
1422
1423 * result = astring;
1424 * index = cur_token;
1425
1426 return MAILIMAP_NO_ERROR;
1427}
1428
1429/*
1430 ASTRING-CHAR = ATOM-CHAR / resp-specials
1431*/
1432
1433static int is_atom_char(char ch);
1434static int is_resp_specials(char ch);
1435
1436static int is_astring_char(char ch)
1437{
1438 if (is_atom_char(ch))
1439 return TRUE;
1440 if (is_resp_specials(ch))
1441 return TRUE;
1442 return FALSE;
1443}
1444
1445/*
1446 atom = 1*ATOM-CHAR
1447*/
1448
1449static int mailimap_atom_parse(mailstream * fd, MMAPString * buffer,
1450 size_t * index, char ** result,
1451 size_t progr_rate,
1452 progress_function * progr_fun)
1453{
1454 return mailimap_custom_string_parse(fd, buffer, index, result,
1455 is_atom_char);
1456}
1457
1458/*
1459 ATOM-CHAR = <any CHAR except atom-specials>
1460*/
1461
1462static int is_atom_specials(char ch);
1463
1464static int is_atom_char(char ch)
1465{
1466 if (is_atom_specials(ch))
1467 return FALSE;
1468
1469 return is_char(ch);
1470}
1471
1472/*
1473 atom-specials = "(" / ")" / "{" / SP / CTL / list-wildcards /
1474 quoted-specials / resp-specials
1475
1476no "}" because there is no need (Mark Crispin)
1477*/
1478
1479static int is_quoted_specials(char ch);
1480static int is_list_wildcards(char ch);
1481
1482static int is_atom_specials(char ch)
1483{
1484 switch (ch) {
1485 case '(':
1486 case ')':
1487 case '{':
1488 case ' ':
1489 return TRUE;
1490 };
1491 if (is_ctl(ch))
1492 return TRUE;
1493 if (is_list_wildcards(ch))
1494 return TRUE;
1495 if (is_resp_specials(ch))
1496 return TRUE;
1497
1498 return is_quoted_specials(ch);
1499}
1500
1501/*
1502 NOT IMPLEMENTED
1503 authenticate = "AUTHENTICATE" SP auth-type *(CRLF base64)
1504*/
1505
1506/*
1507 auth-type = atom
1508 ; Defined by [SASL]
1509*/
1510
1511static int mailimap_auth_type_parse(mailstream * fd, MMAPString * buffer,
1512 size_t * index, char ** result,
1513 size_t progr_rate,
1514 progress_function * progr_fun)
1515{
1516 return mailimap_atom_parse(fd, buffer, index, result,
1517 progr_rate, progr_fun);
1518}
1519
1520/*
1521 base64 = *(4base64-char) [base64-terminal]
1522*/
1523
1524static int is_base64_4char(char * str);
1525static int is_base64_terminal(char * str);
1526
1527static int mailimap_base64_parse(mailstream * fd, MMAPString * buffer,
1528 size_t * index, char ** result,
1529 size_t progr_rate,
1530 progress_function * progr_fun)
1531{
1532 size_t begin;
1533 size_t end;
1534 char * gstr;
1535
1536 begin = * index;
1537 end = begin;
1538
1539 while (is_base64_4char(buffer->str + end))
1540 end += 4;
1541 if (is_base64_terminal(buffer->str + end))
1542 end += 4;
1543 else
1544 return MAILIMAP_ERROR_PARSE;
1545
1546 gstr = malloc(end - begin + 1);
1547 if (gstr == NULL)
1548 return MAILIMAP_ERROR_MEMORY;
1549 strncpy(gstr, buffer->str + begin, end - begin);
1550 gstr[end - begin] = '\0';
1551
1552 * result = gstr;
1553 * index = end;
1554
1555 return MAILIMAP_NO_ERROR;
1556}
1557
1558/*
1559 base64-char = ALPHA / DIGIT / "+" / "/"
1560 ; Case-sensitive
1561*/
1562
1563static int is_base64_char(char ch)
1564{
1565 return (is_alpha(ch) || is_digit(ch) || ch == '+' || ch == '/');
1566}
1567
1568static int is_base64_4char(char * str)
1569{
1570 size_t i;
1571
1572 for (i = 0 ; i < 4 ; i++)
1573 if (!is_base64_char(str[i]))
1574 return FALSE;
1575 return TRUE;
1576}
1577
1578/*
1579 base64-terminal = (2base64-char "==") / (3base64-char "=")
1580*/
1581
1582static int is_base64_terminal(char * str)
1583{
1584 if (str[0] == 0)
1585 return FALSE;
1586 if (str[1] == 0)
1587 return FALSE;
1588 if (str[2] == 0)
1589 return FALSE;
1590 if (str[3] == 0)
1591 return FALSE;
1592
1593 if (is_base64_char(str[0]) || is_base64_char(str[1])
1594 || str[2] == '=' || str[3] == '=')
1595 return TRUE;
1596 if (is_base64_char(str[0]) || is_base64_char(str[1])
1597 || is_base64_char(str[2]) || str[3] == '=')
1598 return TRUE;
1599 return FALSE;
1600}
1601
1602
1603/*
1604 body = "(" (body-type-1part / body-type-mpart) ")"
1605*/
1606
1607static int mailimap_body_parse(mailstream * fd, MMAPString * buffer,
1608 size_t * index,
1609 struct mailimap_body ** result,
1610 size_t progr_rate,
1611 progress_function * progr_fun)
1612{
1613 struct mailimap_body_type_1part * body_type_1part;
1614 struct mailimap_body_type_mpart * body_type_mpart;
1615 struct mailimap_body * body;
1616 size_t cur_token;
1617 int type;
1618 int r;
1619 int res;
1620
1621 cur_token = * index;
1622
1623 body_type_1part = NULL;
1624 body_type_mpart = NULL;
1625
1626 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
1627 if (r != MAILIMAP_NO_ERROR) {
1628 res = r;
1629 goto err;
1630 }
1631
1632 type = MAILIMAP_BODY_ERROR; /* XXX - removes a gcc warning */
1633
1634 r = mailimap_body_type_1part_parse(fd, buffer, &cur_token, &body_type_1part,
1635 progr_rate, progr_fun);
1636 if (r == MAILIMAP_NO_ERROR)
1637 type = MAILIMAP_BODY_1PART;
1638
1639 if (r == MAILIMAP_ERROR_PARSE) {
1640 r = mailimap_body_type_mpart_parse(fd, buffer, &cur_token,
1641 &body_type_mpart,
1642 progr_rate, progr_fun);
1643
1644 if (r == MAILIMAP_NO_ERROR)
1645 type = MAILIMAP_BODY_MPART;
1646 }
1647
1648 if (r != MAILIMAP_NO_ERROR) {
1649 res = r;
1650 goto err;
1651 }
1652
1653 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
1654 if (r != MAILIMAP_NO_ERROR) {
1655 res = r;
1656 goto free;
1657 }
1658
1659 body = mailimap_body_new(type, body_type_1part, body_type_mpart);
1660 if (body == NULL) {
1661 res = MAILIMAP_ERROR_MEMORY;
1662 goto free;
1663 }
1664
1665 * result = body;
1666 * index = cur_token;
1667
1668 return MAILIMAP_NO_ERROR;
1669
1670 free:
1671 if (body_type_1part)
1672 mailimap_body_type_1part_free(body_type_1part);
1673 if (body_type_mpart)
1674 mailimap_body_type_mpart_free(body_type_mpart);
1675 err:
1676 return res;
1677}
1678
1679/*
1680 body-extension = nstring / number /
1681 "(" body-extension *(SP body-extension) ")"
1682 ; Future expansion. Client implementations
1683 ; MUST accept body-extension fields. Server
1684 ; implementations MUST NOT generate
1685 ; body-extension fields except as defined by
1686 ; future standard or standards-track
1687 ; revisions of this specification.
1688*/
1689
1690/*
1691 "(" body-extension *(SP body-extension) ")"
1692*/
1693
1694static int
1695mailimap_body_ext_list_parse(mailstream * fd, MMAPString * buffer,
1696 size_t * index,
1697 clist ** result,
1698 size_t progr_rate,
1699 progress_function * progr_fun)
1700{
1701 size_t cur_token;
1702 clist * list;
1703 int r;
1704 int res;
1705
1706 cur_token = * index;
1707
1708 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
1709 if (r != MAILIMAP_NO_ERROR) {
1710 res = r;
1711 goto err;
1712 }
1713
1714 r = mailimap_struct_spaced_list_parse(fd, buffer,
1715 &cur_token, &list,
1716 (mailimap_struct_parser * )
1717 mailimap_body_extension_parse,
1718 (mailimap_struct_destructor * )
1719 mailimap_body_extension_free,
1720 progr_rate, progr_fun);
1721 if (r != MAILIMAP_NO_ERROR) {
1722 res = r;
1723 goto err;
1724 }
1725
1726 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
1727 if (r != MAILIMAP_NO_ERROR) {
1728 res = r;
1729 goto free_list;
1730 }
1731
1732 * index = cur_token;
1733 * result = list;
1734
1735 return MAILIMAP_NO_ERROR;
1736
1737 free_list:
1738 clist_foreach(list, (clist_func) mailimap_body_extension_free, NULL);
1739 clist_free(list);
1740 err:
1741 return res;
1742}
1743
1744/*
1745 body-extension = nstring / number /
1746 "(" body-extension *(SP body-extension) ")"
1747 ; Future expansion. Client implementations
1748 ; MUST accept body-extension fields. Server
1749 ; implementations MUST NOT generate
1750 ; body-extension fields except as defined by
1751 ; future standard or standards-track
1752 ; revisions of this specification.
1753*/
1754
1755static int
1756mailimap_body_extension_parse(mailstream * fd, MMAPString * buffer,
1757 size_t * index,
1758 struct mailimap_body_extension ** result,
1759 size_t progr_rate,
1760 progress_function * progr_fun)
1761{
1762 size_t cur_token;
1763 uint32_t number;
1764 char * nstring;
1765 clist * body_extension_list;
1766 struct mailimap_body_extension * body_extension;
1767 int type;
1768 int r;
1769 int res;
1770
1771 cur_token = * index;
1772
1773 nstring = NULL;
1774 number = 0;
1775 body_extension_list = NULL;
1776 type = MAILIMAP_BODY_EXTENSION_ERROR; /* XXX - removes a gcc warning */
1777
1778 r = mailimap_nstring_parse(fd, buffer, &cur_token, &nstring, NULL,
1779 progr_rate, progr_fun);
1780 if (r == MAILIMAP_NO_ERROR)
1781 type = MAILIMAP_BODY_EXTENSION_NSTRING;
1782
1783 if (r == MAILIMAP_ERROR_PARSE) {
1784 r = mailimap_number_parse(fd, buffer, &cur_token, &number);
1785
1786 if (r == MAILIMAP_NO_ERROR)
1787 type = MAILIMAP_BODY_EXTENSION_NUMBER;
1788 }
1789
1790 if (r == MAILIMAP_ERROR_PARSE) {
1791 r = mailimap_body_ext_list_parse(fd, buffer, &cur_token,
1792 &body_extension_list,
1793 progr_rate, progr_fun);
1794
1795 if (r == MAILIMAP_NO_ERROR)
1796 type = MAILIMAP_BODY_EXTENSION_LIST;
1797 }
1798
1799 if (r != MAILIMAP_NO_ERROR) {
1800 res = r;
1801 goto err;
1802 }
1803
1804 body_extension = mailimap_body_extension_new(type, nstring, number,
1805 body_extension_list);
1806
1807 if (body_extension == NULL) {
1808 res = MAILIMAP_ERROR_MEMORY;
1809 goto free;
1810 }
1811
1812 * result = body_extension;
1813 * index = cur_token;
1814
1815 return MAILIMAP_NO_ERROR;
1816
1817 free:
1818 if (nstring != NULL)
1819 mailimap_nstring_free(nstring);
1820 if (body_extension_list) {
1821 clist_foreach(body_extension_list,
1822 (clist_func) mailimap_body_extension_free,
1823 NULL);
1824 clist_free(body_extension_list);
1825 }
1826 err:
1827 return res;
1828}
1829
1830/*
1831 body-ext-1part = body-fld-md5 [SP body-fld-dsp [SP body-fld-lang
1832 *(SP body-extension)]]
1833 ; MUST NOT be returned on non-extensible
1834 ; "BODY" fetch
1835*/
1836
1837/*
1838 *(SP body-extension)
1839*/
1840
1841static int
1842mailimap_body_ext_1part_3_parse(mailstream * fd, MMAPString * buffer,
1843 size_t * index,
1844 clist ** body_ext_list,
1845 size_t progr_rate,
1846 progress_function * progr_fun)
1847{
1848 size_t cur_token;
1849 int r;
1850
1851 cur_token = * index;
1852 * body_ext_list = NULL;
1853
1854 r = mailimap_space_parse(fd, buffer, &cur_token);
1855 if (r != MAILIMAP_NO_ERROR)
1856 return r;
1857
1858 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token,
1859 body_ext_list,
1860 (mailimap_struct_parser *)
1861 mailimap_body_extension_parse,
1862 (mailimap_struct_destructor *)
1863 mailimap_body_extension_free,
1864 progr_rate, progr_fun);
1865 if (r != MAILIMAP_NO_ERROR)
1866 return r;
1867
1868 * index = cur_token;
1869
1870 return MAILIMAP_NO_ERROR;
1871}
1872
1873
1874/*
1875 [SP body-fld-lang
1876 *(SP body-extension)]]
1877*/
1878
1879static int
1880mailimap_body_ext_1part_2_parse(mailstream * fd, MMAPString * buffer,
1881 size_t * index,
1882 struct mailimap_body_fld_lang ** fld_lang,
1883 clist ** body_ext_list,
1884 size_t progr_rate,
1885 progress_function * progr_fun)
1886{
1887 size_t cur_token;
1888 int r;
1889
1890 cur_token = * index;
1891 * fld_lang = NULL;
1892 * body_ext_list = NULL;
1893
1894 r = mailimap_space_parse(fd, buffer, &cur_token);
1895 if (r != MAILIMAP_NO_ERROR)
1896 return r;
1897
1898 r = mailimap_body_fld_lang_parse(fd, buffer, &cur_token, fld_lang,
1899 progr_rate, progr_fun);
1900 if (r != MAILIMAP_NO_ERROR)
1901 return r;
1902
1903 r = mailimap_body_ext_1part_3_parse(fd, buffer, &cur_token,
1904 body_ext_list, progr_rate, progr_fun);
1905 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
1906 return r;
1907
1908 * index = cur_token;
1909
1910 return MAILIMAP_NO_ERROR;
1911}
1912
1913
1914/*
1915 SP body-fld-dsp [SP body-fld-lang
1916 *(SP body-extension)]]
1917*/
1918
1919static int
1920mailimap_body_ext_1part_1_parse(mailstream * fd, MMAPString * buffer,
1921 size_t * index,
1922 struct mailimap_body_fld_dsp ** fld_dsp,
1923 struct mailimap_body_fld_lang ** fld_lang,
1924 clist ** body_ext_list,
1925 size_t progr_rate,
1926 progress_function * progr_fun)
1927{
1928 size_t cur_token;
1929 int r;
1930
1931 cur_token = * index;
1932 * fld_dsp = NULL;
1933 * fld_lang = NULL;
1934 * body_ext_list = NULL;
1935
1936 r = mailimap_space_parse(fd, buffer, &cur_token);
1937 if (r != MAILIMAP_NO_ERROR)
1938 return r;
1939
1940 r = mailimap_body_fld_dsp_parse(fd, buffer, &cur_token, fld_dsp,
1941 progr_rate, progr_fun);
1942 if (r != MAILIMAP_NO_ERROR)
1943 return r;
1944
1945 r = mailimap_body_ext_1part_2_parse(fd, buffer, &cur_token,
1946 fld_lang, body_ext_list,
1947 progr_rate, progr_fun);
1948 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
1949 return r;
1950
1951 * index = cur_token;
1952
1953 return MAILIMAP_NO_ERROR;
1954}
1955
1956/*
1957 body-ext-1part = body-fld-md5 [SP body-fld-dsp [SP body-fld-lang
1958 *(SP body-extension)]]
1959 ; MUST NOT be returned on non-extensible
1960 ; "BODY" fetch
1961*/
1962
1963static int
1964mailimap_body_ext_1part_parse(mailstream * fd, MMAPString * buffer,
1965 size_t * index,
1966 struct mailimap_body_ext_1part ** result,
1967 size_t progr_rate,
1968 progress_function * progr_fun)
1969{
1970 size_t cur_token;
1971
1972 char * fld_md5;
1973 struct mailimap_body_fld_dsp * fld_dsp;
1974 struct mailimap_body_fld_lang * fld_lang;
1975 clist * body_ext_list;
1976 int r;
1977 int res;
1978
1979 struct mailimap_body_ext_1part * ext_1part;
1980
1981 cur_token = * index;
1982
1983 fld_md5 = NULL;
1984 fld_dsp = NULL;
1985 fld_lang = NULL;
1986 body_ext_list = NULL;
1987
1988 r = mailimap_body_fld_md5_parse(fd, buffer, &cur_token, &fld_md5,
1989 progr_rate, progr_fun);
1990 if (r != MAILIMAP_NO_ERROR) {
1991 res = r;
1992 goto err;
1993 }
1994
1995 r = mailimap_body_ext_1part_1_parse(fd, buffer, &cur_token,
1996 &fld_dsp,
1997 &fld_lang,
1998 &body_ext_list,
1999 progr_rate, progr_fun);
2000 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
2001 res = r;
2002 goto free;
2003 }
2004
2005 ext_1part = mailimap_body_ext_1part_new(fld_md5, fld_dsp, fld_lang,
2006 body_ext_list);
2007
2008 if (ext_1part == NULL) {
2009 res = MAILIMAP_ERROR_MEMORY;
2010 goto free;
2011 }
2012
2013 * result = ext_1part;
2014 * index = cur_token;
2015
2016 return MAILIMAP_NO_ERROR;
2017
2018 free:
2019 if (body_ext_list) {
2020 clist_foreach(body_ext_list, (clist_func) mailimap_body_extension_free,
2021 NULL);
2022 clist_free(body_ext_list);
2023 }
2024 if (fld_lang)
2025 mailimap_body_fld_lang_free(fld_lang);
2026 if (fld_dsp)
2027 mailimap_body_fld_dsp_free(fld_dsp);
2028 mailimap_body_fld_md5_free(fld_md5);
2029 err:
2030 return res;
2031}
2032
2033
2034/*
2035 body-ext-mpart = body-fld-param [SP body-fld-dsp [SP body-fld-lang
2036 *(SP body-extension)]]
2037 ; MUST NOT be returned on non-extensible
2038 ; "BODY" fetch
2039*/
2040
2041static int
2042mailimap_body_ext_mpart_parse(mailstream * fd, MMAPString * buffer,
2043 size_t * index,
2044 struct mailimap_body_ext_mpart ** result,
2045 size_t progr_rate,
2046 progress_function * progr_fun)
2047{
2048 size_t cur_token;
2049
2050 struct mailimap_body_fld_dsp * fld_dsp;
2051 struct mailimap_body_fld_lang * fld_lang;
2052 struct mailimap_body_fld_param * fld_param;
2053 clist * body_ext_list;
2054
2055 struct mailimap_body_ext_mpart * ext_mpart;
2056 int r;
2057 int res;
2058
2059 cur_token = * index;
2060
2061 fld_param = NULL;
2062 fld_dsp = NULL;
2063 fld_lang = NULL;
2064 body_ext_list = NULL;
2065
2066 r = mailimap_body_fld_param_parse(fd, buffer, &cur_token, &fld_param,
2067 progr_rate, progr_fun);
2068 if (r != MAILIMAP_NO_ERROR) {
2069 res = r;
2070 goto err;
2071 }
2072
2073 r = mailimap_body_ext_1part_1_parse(fd, buffer, &cur_token,
2074 &fld_dsp,
2075 &fld_lang,
2076 &body_ext_list,
2077 progr_rate, progr_fun);
2078 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
2079 res = r;
2080 goto free;
2081 }
2082
2083 ext_mpart = mailimap_body_ext_mpart_new(fld_param, fld_dsp, fld_lang,
2084 body_ext_list);
2085 if (ext_mpart == NULL) {
2086 res = MAILIMAP_ERROR_MEMORY;
2087 goto free;
2088 }
2089
2090 * result = ext_mpart;
2091 * index = cur_token;
2092
2093 return MAILIMAP_NO_ERROR;
2094
2095 free:
2096 if (body_ext_list) {
2097 clist_foreach(body_ext_list, (clist_func) mailimap_body_extension_free,
2098 NULL);
2099 clist_free(body_ext_list);
2100 }
2101 if (fld_lang)
2102 mailimap_body_fld_lang_free(fld_lang);
2103 if (fld_dsp)
2104 mailimap_body_fld_dsp_free(fld_dsp);
2105 if (fld_param != NULL)
2106 mailimap_body_fld_param_free(fld_param);
2107 err:
2108 return res;
2109}
2110
2111/*
2112 body-fields = body-fld-param SP body-fld-id SP body-fld-desc SP
2113 body-fld-enc SP body-fld-octets
2114*/
2115
2116static int
2117mailimap_body_fields_parse(mailstream * fd, MMAPString * buffer,
2118 size_t * index,
2119 struct mailimap_body_fields ** result,
2120 size_t progr_rate,
2121 progress_function * progr_fun)
2122{
2123 struct mailimap_body_fields * body_fields;
2124 size_t cur_token;
2125 struct mailimap_body_fld_param * body_fld_param;
2126 char * body_fld_id;
2127 char * body_fld_desc;
2128 struct mailimap_body_fld_enc * body_fld_enc;
2129 size_t body_fld_octets;
2130 int r;
2131 int res;
2132
2133 body_fld_param = NULL;
2134 body_fld_id = NULL;
2135 body_fld_desc = NULL;
2136 body_fld_enc = NULL;
2137 body_fld_octets = 0;
2138
2139 cur_token = * index;
2140
2141 r = mailimap_body_fld_param_parse(fd, buffer, &cur_token, &body_fld_param,
2142 progr_rate, progr_fun);
2143 if (r != MAILIMAP_NO_ERROR) {
2144 res = r;
2145 goto err;
2146 }
2147
2148 r = mailimap_space_parse(fd, buffer, &cur_token);
2149 if (r != MAILIMAP_NO_ERROR) {
2150 res = r;
2151 goto fld_param_free;
2152 }
2153
2154 r = mailimap_body_fld_id_parse(fd, buffer, &cur_token, &body_fld_id,
2155 progr_rate, progr_fun);
2156 if (r != MAILIMAP_NO_ERROR) {
2157 res = r;
2158 goto fld_param_free;
2159 }
2160
2161 r = mailimap_space_parse(fd, buffer, &cur_token);
2162 if (r != MAILIMAP_NO_ERROR) {
2163 res = r;
2164 goto fld_id_free;
2165 }
2166
2167 r = mailimap_body_fld_desc_parse(fd, buffer, &cur_token, &body_fld_desc,
2168 progr_rate, progr_fun);
2169 if (r != MAILIMAP_NO_ERROR) {
2170 res = r;
2171 goto fld_id_free;
2172 }
2173
2174 r = mailimap_space_parse(fd, buffer, &cur_token);
2175 if (r != MAILIMAP_NO_ERROR) {
2176 res = r;
2177 goto fld_desc_free;
2178 }
2179
2180 r = mailimap_body_fld_enc_parse(fd, buffer, &cur_token, &body_fld_enc,
2181 progr_rate, progr_fun);
2182 if (r != MAILIMAP_NO_ERROR) {
2183 res = r;
2184 goto fld_desc_free;
2185 }
2186
2187 r = mailimap_space_parse(fd, buffer, &cur_token);
2188 if (r != MAILIMAP_NO_ERROR) {
2189 res = r;
2190 goto fld_enc_free;
2191 }
2192
2193 r = mailimap_body_fld_octets_parse(fd, buffer, &cur_token,
2194 &body_fld_octets);
2195 if (r != MAILIMAP_NO_ERROR) {
2196 res = r;
2197 goto fld_enc_free;
2198 }
2199
2200 body_fields = mailimap_body_fields_new(body_fld_param,
2201 body_fld_id,
2202 body_fld_desc,
2203 body_fld_enc,
2204 body_fld_octets);
2205 if (body_fields == NULL) {
2206 res = MAILIMAP_ERROR_MEMORY;
2207 goto fld_enc_free;
2208 }
2209
2210 * result = body_fields;
2211 * index = cur_token;
2212
2213 return MAILIMAP_NO_ERROR;
2214
2215 fld_enc_free:
2216 mailimap_body_fld_enc_free(body_fld_enc);
2217 fld_desc_free:
2218 mailimap_body_fld_desc_free(body_fld_desc);
2219 fld_id_free:
2220 mailimap_body_fld_id_free(body_fld_id);
2221 fld_param_free:
2222 if (body_fld_param != NULL)
2223 mailimap_body_fld_param_free(body_fld_param);
2224 err:
2225 return res;
2226}
2227
2228/*
2229 body-fld-desc = nstring
2230*/
2231
2232static int mailimap_body_fld_desc_parse(mailstream * fd, MMAPString * buffer,
2233 size_t * index, char ** result,
2234 size_t progr_rate,
2235 progress_function * progr_fun)
2236{
2237 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
2238 progr_rate, progr_fun);
2239}
2240
2241/*
2242 body-fld-dsp = "(" string SP body-fld-param ")" / nil
2243*/
2244
2245static int
2246mailimap_body_fld_dsp_parse(mailstream * fd, MMAPString * buffer,
2247 size_t * index,
2248 struct mailimap_body_fld_dsp ** result,
2249 size_t progr_rate,
2250 progress_function * progr_fun)
2251{
2252 size_t cur_token;
2253 char * name;
2254 struct mailimap_body_fld_param * body_fld_param;
2255 struct mailimap_body_fld_dsp * body_fld_dsp;
2256 int res;
2257 int r;
2258
2259 cur_token = * index;
2260 name = NULL;
2261 body_fld_param = NULL;
2262
2263 r = mailimap_nil_parse(fd, buffer, &cur_token);
2264 if (r == MAILIMAP_NO_ERROR) {
2265 * result = NULL;
2266 * index = cur_token;
2267 return MAILIMAP_NO_ERROR;
2268 }
2269
2270 if (r != MAILIMAP_ERROR_PARSE) {
2271 res = r;
2272 goto err;
2273 }
2274
2275 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
2276 if (r != MAILIMAP_NO_ERROR) {
2277 res = r;
2278 goto err;
2279 }
2280
2281 r = mailimap_string_parse(fd, buffer, &cur_token, &name, NULL,
2282 progr_rate, progr_fun);
2283 if (r != MAILIMAP_NO_ERROR) {
2284 res = r;
2285 goto err;
2286 }
2287
2288 r = mailimap_space_parse(fd, buffer, &cur_token);
2289 if (r != MAILIMAP_NO_ERROR) {
2290 res = r;
2291 goto string_free;
2292 }
2293
2294 r = mailimap_body_fld_param_parse(fd, buffer, &cur_token,
2295 &body_fld_param,
2296 progr_rate, progr_fun);
2297 if (r != MAILIMAP_NO_ERROR) {
2298 res = r;
2299 goto string_free;
2300 }
2301
2302 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
2303 if (r != MAILIMAP_NO_ERROR) {
2304 res = r;
2305 goto string_free;
2306 }
2307
2308 body_fld_dsp = mailimap_body_fld_dsp_new(name, body_fld_param);
2309 if (body_fld_dsp == NULL) {
2310 res = MAILIMAP_ERROR_MEMORY;
2311 goto fld_param_free;
2312 }
2313
2314 * index = cur_token;
2315 * result = body_fld_dsp;
2316
2317 return MAILIMAP_NO_ERROR;
2318
2319 fld_param_free:
2320 if (body_fld_param != NULL)
2321 mailimap_body_fld_param_free(body_fld_param);
2322 string_free:
2323 mailimap_string_free(name);
2324 err:
2325 return res;
2326}
2327
2328/*
2329 body-fld-enc = (DQUOTE ("7BIT" / "8BIT" / "BINARY" / "BASE64"/
2330 "QUOTED-PRINTABLE") DQUOTE) / string
2331*/
2332
2333static inline int
2334mailimap_body_fld_known_enc_parse(mailstream * fd, MMAPString * buffer,
2335 size_t * index,
2336 int * result,
2337 size_t progr_rate,
2338 progress_function * progr_fun)
2339{
2340 size_t cur_token;
2341 int type;
2342 int r;
2343 int res;
2344
2345 cur_token = * index;
2346
2347 r = mailimap_dquote_parse(fd, buffer, &cur_token);
2348 if (r != MAILIMAP_NO_ERROR) {
2349 res = r;
2350 goto err;
2351 }
2352
2353 type = mailimap_encoding_get_token_value(fd, buffer, &cur_token);
2354
2355 if (type == -1) {
2356 res = MAILIMAP_ERROR_PARSE;
2357 goto err;
2358 }
2359
2360 r = mailimap_dquote_parse(fd, buffer, &cur_token);
2361 if (r != MAILIMAP_NO_ERROR) {
2362 res = r;
2363 goto err;
2364 }
2365
2366 * result = type;
2367 * index = cur_token;
2368
2369 return MAILIMAP_NO_ERROR;
2370
2371 err:
2372 return res;
2373}
2374
2375static int
2376mailimap_body_fld_enc_parse(mailstream * fd, MMAPString * buffer,
2377 size_t * index,
2378 struct mailimap_body_fld_enc ** result,
2379 size_t progr_rate,
2380 progress_function * progr_fun)
2381{
2382 size_t cur_token;
2383 int type;
2384 char * value;
2385 struct mailimap_body_fld_enc * body_fld_enc;
2386 int r;
2387 int res;
2388
2389 cur_token = * index;
2390
2391 r = mailimap_body_fld_known_enc_parse(fd, buffer, &cur_token,
2392 &type, progr_rate, progr_fun);
2393 if (r == MAILIMAP_NO_ERROR) {
2394 value = NULL;
2395 }
2396 else if (r == MAILIMAP_ERROR_PARSE) {
2397 type = MAILIMAP_BODY_FLD_ENC_OTHER;
2398
2399 r = mailimap_string_parse(fd, buffer, &cur_token, &value, NULL,
2400 progr_rate, progr_fun);
2401 if (r != MAILIMAP_NO_ERROR) {
2402 res = r;
2403 goto err;
2404 }
2405 }
2406 else {
2407 res = r;
2408 goto err;
2409 }
2410
2411 body_fld_enc = mailimap_body_fld_enc_new(type, value);
2412 if (body_fld_enc == NULL) {
2413 res = MAILIMAP_ERROR_MEMORY;
2414 goto value_free;
2415 }
2416
2417 * result = body_fld_enc;
2418 * index = cur_token;
2419
2420 return MAILIMAP_NO_ERROR;
2421
2422 value_free:
2423 if (value)
2424 mailimap_string_free(value);
2425 err:
2426 return res;
2427}
2428
2429/*
2430 body-fld-id = nstring
2431*/
2432
2433static int mailimap_body_fld_id_parse(mailstream * fd, MMAPString * buffer,
2434 size_t * index, char ** result,
2435 size_t progr_rate,
2436 progress_function * progr_fun)
2437{
2438 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
2439 progr_rate, progr_fun);
2440}
2441
2442
2443/*
2444 body-fld-lang = nstring / "(" string *(SP string) ")"
2445*/
2446
2447/*
2448"(" string *(SP string) ")"
2449*/
2450
2451static int
2452mailimap_body_fld_lang_list_parse(mailstream * fd, MMAPString * buffer,
2453 size_t * index, clist ** result,
2454 size_t progr_rate,
2455 progress_function * progr_fun)
2456{
2457 size_t cur_token;
2458 clist * list;
2459 int r;
2460 int res;
2461
2462 cur_token = * index;
2463
2464 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
2465 if (r != MAILIMAP_NO_ERROR) {
2466 res = r;
2467 goto err;
2468 }
2469
2470 list = clist_new();
2471 if (list == NULL) {
2472 res = MAILIMAP_ERROR_MEMORY;
2473 goto err;
2474 }
2475
2476 while (1) {
2477 char * elt;
2478
2479 r = mailimap_string_parse(fd, buffer, &cur_token, &elt, NULL,
2480 progr_rate, progr_fun);
2481 if (r != MAILIMAP_ERROR_PARSE)
2482 break;
2483 else if (r == MAILIMAP_NO_ERROR) {
2484 r = clist_append(list, elt);
2485 if (r < 0) {
2486 mailimap_string_free(elt);
2487 res = r;
2488 goto list_free;
2489 }
2490 }
2491 else {
2492 res = r;
2493 goto list_free;
2494 }
2495 }
2496
2497 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
2498 if (r != MAILIMAP_NO_ERROR) {
2499 res = r;
2500 goto list_free;
2501 }
2502
2503 * index = cur_token;
2504 * result = list;
2505
2506 return MAILIMAP_NO_ERROR;
2507
2508 list_free:
2509 clist_foreach(list, (clist_func) mailimap_string_free, NULL);
2510 clist_free(list);
2511 err:
2512 return res;
2513}
2514
2515/*
2516 body-fld-lang = nstring / "(" string *(SP string) ")"
2517*/
2518
2519static int
2520mailimap_body_fld_lang_parse(mailstream * fd, MMAPString * buffer,
2521 size_t * index,
2522 struct mailimap_body_fld_lang ** result,
2523 size_t progr_rate,
2524 progress_function * progr_fun)
2525{
2526 char * value;
2527 clist * list;
2528 struct mailimap_body_fld_lang * fld_lang;
2529 int type;
2530 int r;
2531 int res;
2532
2533 size_t cur_token;
2534
2535 cur_token = * index;
2536
2537 value = NULL;
2538 list = NULL;
2539 type = MAILIMAP_BODY_FLD_LANG_ERROR; /* XXX - removes a gcc warning */
2540
2541 r = mailimap_nstring_parse(fd, buffer, &cur_token, &value, NULL,
2542 progr_rate, progr_fun);
2543 if (r == MAILIMAP_NO_ERROR)
2544 type = MAILIMAP_BODY_FLD_LANG_SINGLE;
2545
2546 if (r == MAILIMAP_ERROR_PARSE) {
2547 r = mailimap_body_fld_lang_list_parse(fd, buffer, &cur_token, &list,
2548 progr_rate, progr_fun);
2549 if (r == MAILIMAP_NO_ERROR)
2550 type = MAILIMAP_BODY_FLD_LANG_LIST;
2551 }
2552
2553 if (r != MAILIMAP_NO_ERROR) {
2554 res = r;
2555 goto err;
2556 }
2557
2558 fld_lang = mailimap_body_fld_lang_new(type, value, list);
2559 if (fld_lang == NULL) {
2560 res = MAILIMAP_ERROR_MEMORY;
2561 goto free;
2562 }
2563
2564 * index = cur_token;
2565 * result = fld_lang;
2566
2567 return MAILIMAP_NO_ERROR;
2568
2569 free:
2570 if (value)
2571 mailimap_nstring_free(value);
2572 if (list) {
2573 clist_foreach(list, (clist_func) mailimap_string_free, NULL);
2574 clist_free(list);
2575 }
2576 err:
2577 return res;
2578}
2579
2580/*
2581 body-fld-lines = number
2582*/
2583
2584static int mailimap_body_fld_lines_parse(mailstream * fd,
2585 MMAPString * buffer, size_t * index,
2586 uint32_t * result)
2587{
2588 return mailimap_number_parse(fd, buffer, index, result);
2589}
2590
2591/*
2592 body-fld-md5 = nstring
2593*/
2594
2595static int mailimap_body_fld_md5_parse(mailstream * fd, MMAPString * buffer,
2596 size_t * index, char ** result,
2597 size_t progr_rate,
2598 progress_function * progr_fun)
2599{
2600 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
2601 progr_rate, progr_fun);
2602}
2603
2604/*
2605 body-fld-octets = number
2606*/
2607
2608static int mailimap_body_fld_octets_parse(mailstream * fd,
2609 MMAPString * buffer, size_t * index,
2610 uint32_t * result)
2611{
2612 return mailimap_number_parse(fd, buffer, index, result);
2613}
2614
2615/*
2616 body-fld-param = "(" string SP string *(SP string SP string) ")" / nil
2617*/
2618
2619/*
2620 string SP string
2621*/
2622
2623static int
2624mailimap_single_body_fld_param_parse(mailstream * fd, MMAPString * buffer,
2625 size_t * index,
2626 struct mailimap_single_body_fld_param **
2627 result,
2628 size_t progr_rate,
2629 progress_function * progr_fun)
2630{
2631 struct mailimap_single_body_fld_param * param;
2632 char * name;
2633 char * value;
2634 size_t cur_token;
2635 int r;
2636 int res;
2637
2638 cur_token = * index;
2639
2640 name = NULL;
2641 value = NULL;
2642
2643 r = mailimap_string_parse(fd, buffer, &cur_token, &name, NULL,
2644 progr_rate, progr_fun);
2645 if (r != MAILIMAP_NO_ERROR) {
2646 res = r;
2647 goto err;
2648 }
2649
2650 r = mailimap_space_parse(fd, buffer, &cur_token);
2651 if (r != MAILIMAP_NO_ERROR) {
2652 res = r;
2653 goto free_name;
2654 }
2655
2656 r = mailimap_string_parse(fd, buffer, &cur_token, &value, NULL,
2657 progr_rate, progr_fun);
2658 if (r != MAILIMAP_NO_ERROR) {
2659 res = r;
2660 goto free_name;
2661 }
2662
2663 param = mailimap_single_body_fld_param_new(name, value);
2664 if (param == NULL) {
2665 res = MAILIMAP_ERROR_MEMORY;
2666 goto free_value;
2667 }
2668
2669 * result = param;
2670 * index = cur_token;
2671
2672 return MAILIMAP_NO_ERROR;
2673
2674 free_value:
2675 mailimap_string_free(name);
2676 free_name:
2677 mailimap_string_free(value);
2678 err:
2679 return res;
2680}
2681
2682/*
2683 body-fld-param = "(" string SP string *(SP string SP string) ")" / nil
2684*/
2685
2686static int
2687mailimap_body_fld_param_parse(mailstream * fd,
2688 MMAPString * buffer, size_t * index,
2689 struct mailimap_body_fld_param ** result,
2690 size_t progr_rate,
2691 progress_function * progr_fun)
2692{
2693 size_t cur_token;
2694 clist * param_list;
2695 struct mailimap_body_fld_param * fld_param;
2696 int r;
2697 int res;
2698
2699 param_list = NULL;
2700 cur_token = * index;
2701
2702 r = mailimap_nil_parse(fd, buffer, &cur_token);
2703 if (r == MAILIMAP_NO_ERROR) {
2704 * result = NULL;
2705 * index = cur_token;
2706 return MAILIMAP_NO_ERROR;
2707 }
2708
2709 if (r != MAILIMAP_ERROR_PARSE) {
2710 res = r;
2711 goto err;
2712 }
2713
2714 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
2715 if (r != MAILIMAP_NO_ERROR) {
2716 res = r;
2717 goto err;
2718 }
2719
2720 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, &param_list,
2721 (mailimap_struct_parser *)
2722 mailimap_single_body_fld_param_parse,
2723 (mailimap_struct_destructor *)
2724 mailimap_single_body_fld_param_free,
2725 progr_rate, progr_fun);
2726 if (r != MAILIMAP_NO_ERROR) {
2727 res = r;
2728 goto err;
2729 }
2730
2731 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
2732 if (r != MAILIMAP_NO_ERROR) {
2733 res = r;
2734 goto free;
2735 }
2736
2737 fld_param = mailimap_body_fld_param_new(param_list);
2738 if (fld_param == NULL) {
2739 res = MAILIMAP_ERROR_MEMORY;
2740 goto free;
2741 }
2742
2743 * index = cur_token;
2744 * result = fld_param;
2745
2746 return MAILIMAP_NO_ERROR;
2747
2748 free:
2749 clist_foreach(param_list,
2750 (clist_func) mailimap_single_body_fld_param_free,
2751 NULL);
2752 clist_free(param_list);
2753 err:
2754 return res;
2755}
2756
2757/*
2758 body-type-1part = (body-type-basic / body-type-msg / body-type-text)
2759 [SP body-ext-1part]
2760*/
2761
2762static int
2763mailimap_body_type_1part_parse(mailstream * fd, MMAPString * buffer,
2764 size_t * index,
2765 struct mailimap_body_type_1part ** result,
2766 size_t progr_rate,
2767 progress_function * progr_fun)
2768{
2769 size_t cur_token;
2770 struct mailimap_body_type_1part * body_type_1part;
2771 struct mailimap_body_type_basic * body_type_basic;
2772 struct mailimap_body_type_msg * body_type_msg;
2773 struct mailimap_body_type_text * body_type_text;
2774 struct mailimap_body_ext_1part * body_ext_1part;
2775 int type;
2776 size_t final_token;
2777 int r;
2778 int res;
2779
2780 cur_token = * index;
2781
2782 body_type_basic = NULL;
2783 body_type_msg = NULL;
2784 body_type_text = NULL;
2785 body_ext_1part = NULL;
2786
2787 type = MAILIMAP_BODY_TYPE_1PART_ERROR; /* XXX - removes a gcc warning */
2788
2789 r = mailimap_body_type_msg_parse(fd, buffer, &cur_token,
2790 &body_type_msg,
2791 progr_rate, progr_fun);
2792 if (r == MAILIMAP_NO_ERROR)
2793 type = MAILIMAP_BODY_TYPE_1PART_MSG;
2794
2795 if (r == MAILIMAP_ERROR_PARSE) {
2796 r = mailimap_body_type_text_parse(fd, buffer, &cur_token,
2797 &body_type_text,
2798 progr_rate, progr_fun);
2799 if (r == MAILIMAP_NO_ERROR)
2800 type = MAILIMAP_BODY_TYPE_1PART_TEXT;
2801 }
2802
2803 if (r == MAILIMAP_ERROR_PARSE) {
2804 r = mailimap_body_type_basic_parse(fd, buffer, &cur_token,
2805 &body_type_basic,
2806 progr_rate, progr_fun);
2807 if (r == MAILIMAP_NO_ERROR)
2808 type = MAILIMAP_BODY_TYPE_1PART_BASIC;
2809 }
2810
2811 if (r != MAILIMAP_NO_ERROR) {
2812 res = r;
2813 goto err;
2814 }
2815
2816 final_token = cur_token;
2817 body_ext_1part = NULL;
2818
2819 r = mailimap_space_parse(fd, buffer, &cur_token);
2820
2821 if (r == MAILIMAP_NO_ERROR) {
2822 r = mailimap_body_ext_1part_parse(fd, buffer, &cur_token, &body_ext_1part,
2823 progr_rate, progr_fun);
2824 if (r == MAILIMAP_NO_ERROR)
2825 final_token = cur_token;
2826 else if (r == MAILIMAP_ERROR_PARSE) {
2827 /* do nothing */
2828 }
2829 else {
2830 res = r;
2831 goto free;
2832 }
2833 }
2834 else if (r == MAILIMAP_ERROR_PARSE) {
2835 /* do nothing */
2836 }
2837 else {
2838 res = r;
2839 goto free;
2840 }
2841
2842 body_type_1part = mailimap_body_type_1part_new(type, body_type_basic,
2843 body_type_msg, body_type_text,
2844 body_ext_1part);
2845 if (body_type_1part == NULL) {
2846 res = MAILIMAP_ERROR_MEMORY;
2847 goto free;
2848 }
2849
2850 * index = final_token;
2851 * result = body_type_1part;
2852
2853 return MAILIMAP_NO_ERROR;
2854
2855 free:
2856 if (body_type_basic)
2857 mailimap_body_type_basic_free(body_type_basic);
2858 if (body_type_msg)
2859 mailimap_body_type_msg_free(body_type_msg);
2860 if (body_type_text)
2861 mailimap_body_type_text_free(body_type_text);
2862 if (body_ext_1part)
2863 mailimap_body_ext_1part_free(body_ext_1part);
2864 err:
2865 return res;
2866}
2867
2868/*
2869 body-type-basic = media-basic SP body-fields
2870 ; MESSAGE subtype MUST NOT be "RFC822"
2871*/
2872
2873static int
2874mailimap_body_type_basic_parse(mailstream * fd, MMAPString * buffer,
2875 size_t * index,
2876 struct mailimap_body_type_basic ** result,
2877 size_t progr_rate,
2878 progress_function * progr_fun)
2879{
2880 size_t cur_token;
2881 struct mailimap_body_type_basic * body_type_basic;
2882 struct mailimap_media_basic * media_basic;
2883 struct mailimap_body_fields * body_fields;
2884 int r;
2885 int res;
2886
2887 cur_token = * index;
2888
2889 media_basic = NULL;
2890 body_fields = NULL;
2891
2892 r = mailimap_media_basic_parse(fd, buffer, &cur_token, &media_basic,
2893 progr_rate, progr_fun);
2894 if (r != MAILIMAP_NO_ERROR) {
2895 res = r;
2896 goto err;
2897 }
2898
2899 r = mailimap_space_parse(fd, buffer, &cur_token);
2900 if (r != MAILIMAP_NO_ERROR) {
2901 res = r;
2902 goto free_media_basic;
2903 }
2904
2905 r = mailimap_body_fields_parse(fd, buffer, &cur_token, &body_fields,
2906 progr_rate, progr_fun);
2907 if (r != MAILIMAP_NO_ERROR) {
2908 res = r;
2909 goto free_media_basic;
2910 }
2911
2912 body_type_basic = mailimap_body_type_basic_new(media_basic, body_fields);
2913 if (body_type_basic == NULL) {
2914 res = MAILIMAP_ERROR_MEMORY;
2915 goto free_body_fields;
2916 }
2917
2918 * index = cur_token;
2919 * result = body_type_basic;
2920
2921 return MAILIMAP_NO_ERROR;
2922
2923 free_body_fields:
2924 mailimap_body_fields_free(body_fields);
2925 free_media_basic:
2926 mailimap_media_basic_free(media_basic);
2927 err:
2928 return res;
2929}
2930
2931/*
2932 body-type-mpart = 1*body SP media-subtype
2933 [SP body-ext-mpart]
2934*/
2935
2936static int
2937mailimap_body_type_mpart_parse(mailstream * fd,
2938 MMAPString * buffer,
2939 size_t * index,
2940 struct mailimap_body_type_mpart ** result,
2941 size_t progr_rate,
2942 progress_function * progr_fun)
2943{
2944 struct mailimap_body_type_mpart * body_type_mpart;
2945 clist * body_list;
2946 size_t cur_token;
2947 size_t final_token;
2948 char * media_subtype;
2949 struct mailimap_body_ext_mpart * body_ext_mpart;
2950 int r;
2951 int res;
2952
2953 cur_token = * index;
2954
2955 body_list = NULL;
2956 media_subtype = NULL;
2957 body_ext_mpart = NULL;
2958
2959 r = mailimap_struct_multiple_parse(fd, buffer, &cur_token,
2960 &body_list,
2961 (mailimap_struct_parser *)
2962 mailimap_body_parse,
2963 (mailimap_struct_destructor *)
2964 mailimap_body_free,
2965 progr_rate, progr_fun);
2966 if (r != MAILIMAP_NO_ERROR) {
2967 res = r;
2968 goto err;
2969 }
2970
2971 r = mailimap_space_parse(fd, buffer, &cur_token);
2972 if (r != MAILIMAP_NO_ERROR) {
2973 res = r;
2974 goto free_body_list;
2975 }
2976
2977 r = mailimap_media_subtype_parse(fd, buffer, &cur_token, &media_subtype,
2978 progr_rate, progr_fun);
2979 if (r != MAILIMAP_NO_ERROR) {
2980 res = r;
2981 goto free_body_list;
2982 }
2983
2984 final_token = cur_token;
2985
2986 body_ext_mpart = NULL;
2987
2988 r = mailimap_space_parse(fd, buffer, &cur_token);
2989 if (r == MAILIMAP_NO_ERROR) {
2990 r = mailimap_body_ext_mpart_parse(fd, buffer, &cur_token, &body_ext_mpart,
2991 progr_rate, progr_fun);
2992 if (r == MAILIMAP_NO_ERROR)
2993 final_token = cur_token;
2994 else if (r == MAILIMAP_ERROR_PARSE) {
2995 /* do nothing */
2996 }
2997 else {
2998 res = r;
2999 goto free_body_list;
3000 }
3001 }
3002 else if (r == MAILIMAP_ERROR_PARSE) {
3003 /* do nothing */
3004 }
3005 else {
3006 res = r;
3007 goto free_body_list;
3008 }
3009
3010 body_type_mpart = mailimap_body_type_mpart_new(body_list, media_subtype,
3011 body_ext_mpart);
3012 if (body_type_mpart == NULL) {
3013 res = MAILIMAP_ERROR_MEMORY;
3014 goto free_body_ext_mpart;
3015 }
3016
3017 * result = body_type_mpart;
3018 * index = final_token;
3019
3020 return MAILIMAP_NO_ERROR;
3021
3022 free_body_ext_mpart:
3023 if (body_ext_mpart)
3024 mailimap_body_ext_mpart_free(body_ext_mpart);
3025 mailimap_media_subtype_free(media_subtype);
3026 free_body_list:
3027 clist_foreach(body_list, (clist_func) mailimap_body_free, NULL);
3028 clist_free(body_list);
3029 err:
3030 return res;
3031}
3032
3033/*
3034 body-type-msg = media-message SP body-fields SP envelope
3035 SP body SP body-fld-lines
3036*/
3037
3038static int
3039mailimap_body_type_msg_parse(mailstream * fd, MMAPString * buffer,
3040 size_t * index,
3041 struct mailimap_body_type_msg ** result,
3042 size_t progr_rate,
3043 progress_function * progr_fun)
3044{
3045 struct mailimap_body_fields * body_fields;
3046 struct mailimap_envelope * envelope;
3047 struct mailimap_body * body;
3048 uint32_t body_fld_lines;
3049 struct mailimap_body_type_msg * body_type_msg;
3050 size_t cur_token;
3051 int r;
3052 int res;
3053
3054 cur_token = * index;
3055
3056 body_fields = NULL;
3057 envelope = NULL;
3058 body = NULL;
3059 body_fld_lines = 0;
3060
3061 r = mailimap_media_message_parse(fd, buffer, &cur_token);
3062 if (r != MAILIMAP_NO_ERROR) {
3063 res = r;
3064 goto err;
3065 }
3066
3067 r = mailimap_space_parse(fd, buffer, &cur_token);
3068 if (r != MAILIMAP_NO_ERROR) {
3069 res = r;
3070 goto err;
3071 }
3072
3073 r = mailimap_body_fields_parse(fd, buffer, &cur_token, &body_fields,
3074 progr_rate, progr_fun);
3075 if (r != MAILIMAP_NO_ERROR) {
3076 res = r;
3077 goto err;
3078 }
3079
3080 r = mailimap_space_parse(fd, buffer, &cur_token);
3081 if (r != MAILIMAP_NO_ERROR) {
3082 res = r;
3083 goto body_fields;
3084 }
3085
3086 r = mailimap_envelope_parse(fd, buffer, &cur_token, &envelope,
3087 progr_rate, progr_fun);
3088 if (r != MAILIMAP_NO_ERROR) {
3089 res = r;
3090 goto body_fields;
3091 }
3092
3093 r = mailimap_space_parse(fd, buffer, &cur_token);
3094 if (r != MAILIMAP_NO_ERROR) {
3095 res = r;
3096 goto envelope;
3097 }
3098
3099 r = mailimap_body_parse(fd, buffer, &cur_token, &body,
3100 progr_rate, progr_fun);
3101 if (r != MAILIMAP_NO_ERROR) {
3102 res = r;
3103 goto envelope;
3104 }
3105
3106 r = mailimap_space_parse(fd, buffer, &cur_token);
3107 if (r != MAILIMAP_NO_ERROR) {
3108 res = r;
3109 goto body;
3110 }
3111
3112 r = mailimap_body_fld_lines_parse(fd, buffer, &cur_token,
3113 &body_fld_lines);
3114 if (r != MAILIMAP_NO_ERROR) {
3115 res = r;
3116 goto body;
3117 }
3118
3119 body_type_msg = mailimap_body_type_msg_new(body_fields, envelope,
3120 body, body_fld_lines);
3121 if (body_type_msg == NULL) {
3122 res = MAILIMAP_ERROR_MEMORY;
3123 goto body;
3124 }
3125
3126 * result = body_type_msg;
3127 * index = cur_token;
3128
3129 return MAILIMAP_NO_ERROR;
3130
3131 body:
3132 mailimap_body_free(body);
3133 envelope:
3134 mailimap_envelope_free(envelope);
3135 body_fields:
3136 mailimap_body_fields_free(body_fields);
3137 err:
3138 return res;
3139}
3140
3141/*
3142 body-type-text = media-text SP body-fields SP body-fld-lines
3143*/
3144
3145static int
3146mailimap_body_type_text_parse(mailstream * fd, MMAPString * buffer,
3147 size_t * index,
3148 struct mailimap_body_type_text **
3149 result,
3150 size_t progr_rate,
3151 progress_function * progr_fun)
3152{
3153 char * media_text;
3154 struct mailimap_body_fields * body_fields;
3155 uint32_t body_fld_lines;
3156 struct mailimap_body_type_text * body_type_text;
3157 size_t cur_token;
3158 int r;
3159 int res;
3160
3161 media_text = NULL;
3162 body_fields = NULL;
3163 body_fld_lines = 0;
3164
3165 cur_token = * index;
3166
3167 r = mailimap_media_text_parse(fd, buffer, &cur_token, &media_text,
3168 progr_rate, progr_fun);
3169 if (r != MAILIMAP_NO_ERROR) {
3170 res = r;
3171 goto err;
3172 }
3173
3174 r = mailimap_space_parse(fd, buffer, &cur_token);
3175 if (r != MAILIMAP_NO_ERROR) {
3176 res = r;
3177 goto free_media_text;
3178 }
3179
3180 r = mailimap_body_fields_parse(fd, buffer, &cur_token, &body_fields,
3181 progr_rate, progr_fun);
3182 if (r != MAILIMAP_NO_ERROR) {
3183 res = r;
3184 goto free_media_text;
3185 }
3186
3187 r = mailimap_space_parse(fd, buffer, &cur_token);
3188 if (r != MAILIMAP_NO_ERROR) {
3189 res = r;
3190 goto free_body_fields;
3191 }
3192
3193 r = mailimap_body_fld_lines_parse(fd, buffer, &cur_token, &body_fld_lines);
3194 if (r != MAILIMAP_NO_ERROR) {
3195 res = r;
3196 goto free_body_fields;
3197 }
3198
3199 body_type_text = mailimap_body_type_text_new(media_text, body_fields,
3200 body_fld_lines);
3201 if (body_type_text == NULL) {
3202 res = MAILIMAP_ERROR_MEMORY;
3203 goto free_body_fields;
3204 }
3205
3206 * result = body_type_text;
3207 * index = cur_token;
3208
3209 return MAILIMAP_NO_ERROR;
3210
3211 free_body_fields:
3212 mailimap_body_fields_free(body_fields);
3213 free_media_text:
3214 mailimap_media_text_free(media_text);
3215 err:
3216 return res;
3217}
3218
3219
3220/*
3221 capability = ("AUTH=" auth-type) / atom
3222 ; New capabilities MUST begin with "X" or be
3223 ; registered with IANA as standard or
3224 ; standards-track
3225*/
3226
3227static int
3228mailimap_capability_parse(mailstream * fd, MMAPString * buffer,
3229 size_t * index,
3230 struct mailimap_capability ** result,
3231 size_t progr_rate,
3232 progress_function * progr_fun)
3233{
3234 size_t cur_token;
3235 int type;
3236 char * auth_type;
3237 char * atom;
3238 struct mailimap_capability * cap;
3239 int r;
3240 int res;
3241
3242 cur_token = * index;
3243
3244 auth_type = NULL;
3245 atom = NULL;
3246
3247 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "AUTH=");
3248 switch (r) {
3249 case MAILIMAP_NO_ERROR:
3250 type = MAILIMAP_CAPABILITY_AUTH_TYPE;
3251
3252 r = mailimap_auth_type_parse(fd, buffer, &cur_token, &auth_type,
3253 progr_rate, progr_fun);
3254 if (r != MAILIMAP_NO_ERROR) {
3255 res = r;
3256 goto err;
3257 }
3258 break;
3259
3260 case MAILIMAP_ERROR_PARSE:
3261 r = mailimap_atom_parse(fd, buffer, &cur_token, &atom,
3262 progr_rate, progr_fun);
3263 if (r != MAILIMAP_NO_ERROR) {
3264 res = r;
3265 goto err;
3266 }
3267
3268 type = MAILIMAP_CAPABILITY_NAME;
3269 break;
3270
3271 default:
3272 res = r;
3273 goto err;
3274 }
3275
3276 cap = mailimap_capability_new(type, auth_type, atom);
3277 if (cap == NULL) {
3278 res = MAILIMAP_ERROR_MEMORY;
3279 goto free;
3280 }
3281
3282 * result = cap;
3283 * index = cur_token;
3284
3285 return MAILIMAP_NO_ERROR;
3286
3287 free:
3288 if (auth_type)
3289 mailimap_auth_type_free(auth_type);
3290 if (atom)
3291 mailimap_atom_free(atom);
3292 err:
3293 return res;
3294}
3295
3296/*
3297 capability-data = "CAPABILITY" *(SP capability) SP "IMAP4rev1"
3298 *(SP capability)
3299 ; IMAP4rev1 servers which offer RFC 1730
3300 ; compatibility MUST list "IMAP4" as the first
3301 ; capability.
3302*/
3303
3304/*
3305 SP capability *(SP capability)
3306*/
3307
3308static int mailimap_capability_list_parse(mailstream * fd,
3309 MMAPString * buffer,
3310 size_t * index,
3311 clist ** result,
3312 size_t progr_rate,
3313 progress_function * progr_fun)
3314{
3315 size_t cur_token;
3316 clist * list;
3317 int r;
3318
3319 cur_token = * index;
3320
3321 r = mailimap_space_parse(fd, buffer, &cur_token);
3322 if (r != MAILIMAP_NO_ERROR)
3323 return r;
3324
3325 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, &list,
3326 (mailimap_struct_parser *)
3327 mailimap_capability_parse,
3328 (mailimap_struct_destructor *)
3329 mailimap_capability_free,
3330 progr_rate, progr_fun);
3331 if (r != MAILIMAP_NO_ERROR)
3332 return r;
3333
3334 * index = cur_token;
3335 * result = list;
3336
3337 return MAILIMAP_NO_ERROR;
3338}
3339
3340static int
3341mailimap_capability_data_parse(mailstream * fd, MMAPString * buffer,
3342 size_t * index,
3343 struct mailimap_capability_data ** result,
3344 size_t progr_rate,
3345 progress_function * progr_fun)
3346{
3347 size_t cur_token;
3348 clist * cap_list;
3349#if 0
3350 clist * cap_list_2;
3351#endif
3352 struct mailimap_capability_data * cap_data;
3353 int r;
3354 int res;
3355
3356 cur_token = * index;
3357
3358 cap_list = NULL;
3359#if 0
3360 cap_list_2 = NULL;
3361#endif
3362
3363 r = mailimap_token_case_insensitive_parse(fd, buffer,
3364 &cur_token, "CAPABILITY");
3365 if (r != MAILIMAP_NO_ERROR) {
3366 res = r;
3367 goto err;
3368 }
3369
3370 r = mailimap_capability_list_parse(fd, buffer, &cur_token,
3371 &cap_list,
3372 progr_rate, progr_fun);
3373
3374 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
3375 res = r;
3376 goto err;
3377 }
3378
3379#if 0
3380 if (!mailimap_space_parse(fd, buffer, &cur_token)) {
3381 res = r;
3382 goto free_list;
3383 }
3384
3385 if (!mailimap_token_case_insensitive_parse(fd, buffer,
3386 &cur_token, "IMAP4rev1"))
3387 goto free_list;
3388
3389 r = mailimap_capability_list_parse(fd, buffer, &cur_token,
3390 &cap_list_2,
3391 progr_rate, progr_fun);
3392
3393 cap_list = g_list_concat(cap_list, cap_list_2);
3394#endif
3395
3396 cap_data = mailimap_capability_data_new(cap_list);
3397 if (cap_data == NULL) {
3398 res = MAILIMAP_ERROR_MEMORY;
3399 goto free_list;
3400 }
3401
3402 * result = cap_data;
3403 * index = cur_token;
3404
3405 return MAILIMAP_NO_ERROR;
3406
3407 free_list:
3408 if (cap_list) {
3409 clist_foreach(cap_list, (clist_func) mailimap_capability_free, NULL);
3410 clist_free(cap_list);
3411 }
3412 err:
3413 return res;
3414}
3415
3416/*
3417 UNIMPLEMENTED BECAUSE UNUSED (only in literal)
3418 CHAR8 = %x01-ff
3419 ; any OCTET except NUL, %x00
3420*/
3421
3422/*
3423static gboolean is_char8(gchar ch)
3424{
3425 return (ch != 0x00);
3426}
3427*/
3428
3429
3430/*
3431UNIMPLEMENTED
3432 command = tag SP (command-any / command-auth / command-nonauth /
3433 command-select) CRLF
3434 ; Modal based on state
3435*/
3436
3437/*
3438UNIMPLEMENTED
3439 command-any = "CAPABILITY" / "LOGOUT" / "NOOP" / x-command
3440 ; Valid in all states
3441*/
3442
3443/*
3444UNIMPLEMENTED
3445 command-auth = append / create / delete / examine / list / lsub /
3446 rename / select / status / subscribe / unsubscribe
3447 ; Valid only in Authenticated or Selected state
3448*/
3449
3450/*
3451UNIMPLEMENTED
3452 command-nonauth = login / authenticate
3453 ; Valid only when in Not Authenticated state
3454*/
3455
3456/*
3457UNIMPLEMENTED
3458 command-select = "CHECK" / "CLOSE" / "EXPUNGE" / copy / fetch / store /
3459 uid / search
3460 ; Valid only when in Selected state
3461*/
3462
3463/*
3464 continue-req = "+" SP (resp-text / base64) CRLF
3465*/
3466
3467int
3468mailimap_continue_req_parse(mailstream * fd, MMAPString * buffer,
3469 size_t * index,
3470 struct mailimap_continue_req ** result,
3471 size_t progr_rate,
3472 progress_function * progr_fun)
3473{
3474 struct mailimap_resp_text * resp_text;
3475 size_t cur_token;
3476 struct mailimap_continue_req * cont_req;
3477 char * base64;
3478 int type;
3479 int r;
3480 int res;
3481
3482 cur_token = * index;
3483
3484 r = mailimap_plus_parse(fd, buffer, &cur_token);
3485 if (r != MAILIMAP_NO_ERROR)
3486 return r;
3487
3488 r = mailimap_space_parse(fd, buffer, &cur_token);
3489 if (r != MAILIMAP_NO_ERROR)
3490 return r;
3491
3492 resp_text = NULL;
3493 base64 = NULL;
3494
3495 type = MAILIMAP_CONTINUE_REQ_ERROR; /* XXX - removes a gcc warning */
3496
3497 r = mailimap_base64_parse(fd, buffer, &cur_token, &base64,
3498 progr_rate, progr_fun);
3499
3500 if (r == MAILIMAP_NO_ERROR)
3501 type = MAILIMAP_CONTINUE_REQ_BASE64;
3502
3503 if (r == MAILIMAP_ERROR_PARSE) {
3504 r = mailimap_resp_text_parse(fd, buffer, &cur_token, &resp_text,
3505 progr_rate, progr_fun);
3506
3507 if (r == MAILIMAP_NO_ERROR)
3508 type = MAILIMAP_CONTINUE_REQ_TEXT;
3509 }
3510
3511 if (r != MAILIMAP_NO_ERROR) {
3512 res = r;
3513 goto err;
3514 }
3515
3516 r = mailimap_crlf_parse(fd, buffer, &cur_token);
3517 if (r != MAILIMAP_NO_ERROR) {
3518 res = r;
3519 goto free;
3520 }
3521
3522 cont_req = mailimap_continue_req_new(type, resp_text, base64);
3523 if (cont_req == NULL) {
3524 res = MAILIMAP_ERROR_MEMORY;
3525 goto free;
3526 }
3527
3528 * result = cont_req;
3529 * index = cur_token;
3530
3531 return MAILIMAP_NO_ERROR;
3532
3533 free:
3534 if (base64 != NULL)
3535 mailimap_base64_free(base64);
3536 if (resp_text != NULL)
3537 mailimap_resp_text_free(resp_text);
3538 err:
3539 return res;
3540}
3541
3542/*
3543 UNIMPLEMENTED
3544 copy = "COPY" SP set SP mailbox
3545*/
3546
3547/*
3548 UNIMPLEMENTED
3549 create = "CREATE" SP mailbox
3550 ; Use of INBOX gives a NO error
3551*/
3552
3553/*
3554 UNIMPLEMENTED
3555 date = date-text / DQUOTE date-text DQUOTE
3556*/
3557
3558/*
3559 UNIMPLEMENTED
3560 date-day = 1*2DIGIT
3561 ; Day of month
3562*/
3563
3564/*
3565static gboolean mailimap_date_day_parse(mailstream * fd,
3566 MMAPString * buffer,
3567 guint32 * index,
3568 gint * result)
3569{
3570 guint32 cur_token;
3571 gint digit;
3572 gint number;
3573
3574 cur_token = * index;
3575
3576 if (!mailimap_digit_parse(fd, buffer, &cur_token, &digit))
3577 return FALSE;
3578
3579 number = digit;
3580
3581 if (mailimap_digit_parse(fd, buffer, &cur_token, &digit))
3582 number = number * 10 + digit;
3583
3584 * result = number;
3585 * index = cur_token;
3586
3587 return TRUE;
3588}
3589*/
3590
3591/*
3592 date-day-fixed = (SP DIGIT) / 2DIGIT
3593 ; Fixed-format version of date-day
3594*/
3595
3596static int mailimap_date_day_fixed_parse(mailstream * fd,
3597 MMAPString * buffer,
3598 size_t * index,
3599 int * result)
3600{
3601#ifdef UNSTRICT_SYNTAX
3602 size_t cur_token;
3603 uint32_t day;
3604 int r;
3605
3606 cur_token = * index;
3607
3608 r = mailimap_number_parse(fd, buffer, &cur_token, &day);
3609 if (r != MAILIMAP_NO_ERROR)
3610 return r;
3611
3612 * index = cur_token;
3613 * result = day;
3614
3615 return MAILIMAP_NO_ERROR;
3616
3617#else
3618 size_t cur_token;
3619 int r;
3620
3621 cur_token = * index;
3622
3623 if (mailimap_space_parse(fd, buffer, &cur_token)) {
3624 int digit;
3625
3626 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit);
3627 if (r != MAILIMAP_NO_ERROR)
3628 return r;
3629
3630 * result = digit;
3631 * index = cur_token;
3632
3633 return MAILIMAP_NO_ERROR;
3634 }
3635 else {
3636 int digit1;
3637 int digit2;
3638
3639 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit1);
3640 if (r != MAILIMAP_NO_ERROR)
3641 return r;
3642 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit2);
3643 if (r != MAILIMAP_NO_ERROR)
3644 return r;
3645
3646 * result = digit1 * 10 + digit2;
3647 * index = cur_token;
3648
3649 return MAILIMAP_NO_ERROR;
3650 }
3651#endif
3652}
3653
3654
3655/*
3656 date-month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" /
3657 "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
3658*/
3659
3660static int mailimap_date_month_parse(mailstream * fd, MMAPString * buffer,
3661 size_t * index, int * result)
3662{
3663 size_t cur_token;
3664 int month;
3665
3666 cur_token = * index;
3667
3668 month = mailimap_month_get_token_value(fd, buffer, &cur_token);
3669 if (month == -1)
3670 return MAILIMAP_ERROR_PARSE;
3671
3672 * result = month;
3673 * index = cur_token;
3674
3675 return MAILIMAP_NO_ERROR;
3676}
3677
3678/*
3679 UNIMPLEMENTED
3680 date-text = date-day "-" date-month "-" date-year
3681*/
3682
3683/*
3684static struct mailimap_date_text *
3685mailimap_date_text_new(gint day, gint month, gint year)
3686{
3687 struct mailimap_date_text * date_text;
3688
3689 date_text = g_new(struct mailimap_date_text, 1);
3690 if (date_text == NULL)
3691 return NULL;
3692
3693 date_text->day = day;
3694 date_text->month = month;
3695 date_text->year = year;
3696
3697 return date_text;
3698}
3699
3700static void mailimap_date_text_free(struct mailimap_date_text * date_text)
3701{
3702 g_free(date_text);
3703}
3704
3705static gboolean
3706mailimap_date_text_parse(mailstream * fd, MMAPString * buffer,
3707 guint32 * index, struct mailimap_date_text ** result)
3708{
3709 struct mailimap_date_text * date_text;
3710 gint day;
3711 gint month;
3712 gint year;
3713 guint32 cur_token;
3714
3715 cur_token = * index;
3716
3717 if (!mailimap_date_day_parse(fd, buffer, &cur_token, &day))
3718 return FALSE;
3719
3720 if (!mailimap_minus_parse(fd, buffer, &cur_token))
3721 return FALSE;
3722
3723 if (!mailimap_date_month_parse(fd, buffer, &cur_token, &month))
3724 return FALSE;
3725
3726 if (!mailimap_minus_parse(fd, buffer, &cur_token))
3727 return FALSE;
3728
3729 if (!mailimap_date_year_parse(fd, buffer, &cur_token, &year))
3730 return FALSE;
3731
3732 date_text = mailimap_date_text_new(day, month, year);
3733 if (date_text == NULL)
3734 return FALSE;
3735
3736 * result = date_text;
3737 * index = cur_token;
3738
3739 return TRUE;
3740}
3741*/
3742
3743/*
3744 date-year = 4DIGIT
3745*/
3746
3747static int mailimap_date_year_parse(mailstream * fd, MMAPString * buffer,
3748 size_t * index, int * result)
3749{
3750#ifdef UNSTRICT_SYNTAX
3751 uint32_t year;
3752 int r;
3753 size_t cur_token;
3754
3755 cur_token = * index;
3756
3757 r = mailimap_number_parse(fd, buffer, &cur_token, &year);
3758 if (r != MAILIMAP_NO_ERROR)
3759 return r;
3760
3761 * result = year;
3762 * index = cur_token;
3763
3764 return MAILIMAP_NO_ERROR;
3765#else
3766 int i;
3767 size_t cur_token;
3768 int year;
3769 int digit;
3770 int r;
3771
3772 cur_token = * index;
3773 year = 0;
3774
3775 for(i = 0 ; i < 4 ; i ++) {
3776 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit);
3777 if (r != MAILIMAP_NO_ERROR)
3778 return r;
3779 year = year * 10 + digit;
3780 }
3781
3782 * result = year;
3783 * index = cur_token;
3784
3785 return MAILIMAP_NO_ERROR;
3786#endif
3787}
3788
3789/*
3790 date-time = DQUOTE date-day-fixed "-" date-month "-" date-year
3791 SP time SP zone DQUOTE
3792*/
3793
3794static int mailimap_date_time_parse(mailstream * fd, MMAPString * buffer,
3795 size_t * index,
3796 struct mailimap_date_time ** result,
3797 size_t progr_rate,
3798 progress_function * progr_fun)
3799{
3800 int day;
3801 int month;
3802 int year;
3803 int hour;
3804 int min;
3805 int sec;
3806 struct mailimap_date_time * date_time;
3807 size_t cur_token;
3808 int zone;
3809 int r;
3810
3811 cur_token = * index;
3812
3813 r = mailimap_dquote_parse(fd, buffer, &cur_token);
3814 if (r != MAILIMAP_NO_ERROR)
3815 return r;
3816
3817 r = mailimap_date_day_fixed_parse(fd, buffer, &cur_token, &day);
3818 if (r != MAILIMAP_NO_ERROR)
3819 return r;
3820
3821 r = mailimap_minus_parse(fd, buffer, &cur_token);
3822 if (r != MAILIMAP_NO_ERROR)
3823 return r;
3824
3825 r = mailimap_date_month_parse(fd, buffer, &cur_token, &month);
3826 if (r != MAILIMAP_NO_ERROR)
3827 return r;
3828
3829 r = mailimap_minus_parse(fd, buffer, &cur_token);
3830 if (r != MAILIMAP_NO_ERROR)
3831 return r;
3832
3833 r = mailimap_date_year_parse(fd, buffer, &cur_token, &year);
3834 if (r != MAILIMAP_NO_ERROR)
3835 return r;
3836
3837 r = mailimap_space_parse(fd, buffer, &cur_token);
3838 if (r != MAILIMAP_NO_ERROR)
3839 return r;
3840
3841 r = mailimap_time_parse(fd, buffer, &cur_token, &hour, &min, &sec);
3842 if (r != MAILIMAP_NO_ERROR)
3843 return r;
3844
3845 r = mailimap_space_parse(fd, buffer, &cur_token);
3846 if (r != MAILIMAP_NO_ERROR)
3847 return r;
3848
3849 r = mailimap_zone_parse(fd, buffer, &cur_token, &zone);
3850 if (r != MAILIMAP_NO_ERROR)
3851 return r;
3852
3853 r = mailimap_dquote_parse(fd, buffer, &cur_token);
3854 if (r != MAILIMAP_NO_ERROR)
3855 return r;
3856
3857 date_time = mailimap_date_time_new(day, month, year, hour, min, sec, zone);
3858 if (date_time == NULL)
3859 return MAILIMAP_ERROR_MEMORY;
3860
3861 * result = date_time;
3862 * index = cur_token;
3863
3864 return MAILIMAP_NO_ERROR;
3865}
3866
3867
3868/*
3869 UNIMPLEMENTED
3870 delete = "DELETE" SP mailbox
3871 ; Use of INBOX gives a NO error
3872*/
3873
3874/*
3875 digit-nz = %x31-39
3876 ; 1-9
3877*/
3878
3879#ifndef UNSTRICT_SYNTAX
3880static int is_digit_nz(char ch)
3881{
3882 return (ch >= '1') && (ch <= '9');
3883}
3884
3885static int mailimap_digit_nz_parse(mailstream * fd, MMAPString * buffer,
3886 size_t * index, int * result)
3887{
3888 size_t cur_token;
3889
3890 cur_token = * index;
3891
3892 if (is_digit_nz(buffer->str[cur_token])) {
3893 * result = buffer->str[cur_token] - '0';
3894 cur_token ++;
3895 * index = cur_token;
3896 return MAILIMAP_NO_ERROR;
3897 }
3898 else
3899 return MAILIMAP_ERROR_PARSE;
3900}
3901#endif
3902
3903/*
3904 envelope = "(" env-date SP env-subject SP env-from SP env-sender SP
3905 env-reply-to SP env-to SP env-cc SP env-bcc SP
3906 env-in-reply-to SP env-message-id ")"
3907*/
3908
3909static int mailimap_envelope_parse(mailstream * fd, MMAPString * buffer,
3910 size_t * index,
3911 struct mailimap_envelope ** result,
3912 size_t progr_rate,
3913 progress_function * progr_fun)
3914{
3915 size_t cur_token;
3916 char * date;
3917 char * subject;
3918 struct mailimap_env_from * from;
3919 struct mailimap_env_sender * sender;
3920 struct mailimap_env_reply_to * reply_to;
3921 struct mailimap_env_to * to;
3922 struct mailimap_env_cc * cc;
3923 struct mailimap_env_bcc * bcc;
3924 char * in_reply_to;
3925 char * message_id;
3926 struct mailimap_envelope * envelope;
3927 int r;
3928 int res;
3929
3930 date = NULL;
3931 subject = NULL;
3932 from = NULL;
3933 sender = NULL;
3934 reply_to = NULL;
3935 to = NULL;
3936 cc = NULL;
3937 bcc = NULL;
3938 in_reply_to = NULL;
3939 message_id = NULL;
3940
3941 cur_token = * index;
3942
3943 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
3944 if (r != MAILIMAP_NO_ERROR) {
3945 res = r;
3946 goto err;
3947 }
3948
3949 r = mailimap_env_date_parse(fd, buffer, &cur_token, &date,
3950 progr_rate, progr_fun);
3951 if (r != MAILIMAP_NO_ERROR) {
3952 res = r;
3953 goto err;
3954 }
3955
3956 r = mailimap_space_parse(fd, buffer, &cur_token);
3957 if (r != MAILIMAP_NO_ERROR) {
3958 res = r;
3959 goto date;
3960 }
3961
3962 r = mailimap_env_subject_parse(fd, buffer, &cur_token, &subject,
3963 progr_rate, progr_fun);
3964 if (r != MAILIMAP_NO_ERROR) {
3965 res = r;
3966 goto date;
3967 }
3968
3969 r = mailimap_space_parse(fd, buffer, &cur_token);
3970 if (r != MAILIMAP_NO_ERROR) {
3971 res = r;
3972 goto subject;
3973 }
3974
3975 r = mailimap_env_from_parse(fd, buffer, &cur_token, &from,
3976 progr_rate, progr_fun);
3977 if (r != MAILIMAP_NO_ERROR) {
3978 res = r;
3979 goto subject;
3980 }
3981
3982 r = mailimap_space_parse(fd, buffer, &cur_token);
3983 if (r != MAILIMAP_NO_ERROR) {
3984 res = r;
3985 goto from;
3986 }
3987
3988 r = mailimap_env_sender_parse(fd, buffer, &cur_token, &sender,
3989 progr_rate, progr_fun);
3990 if (r != MAILIMAP_NO_ERROR) {
3991 res = r;
3992 goto from;
3993 }
3994
3995 r = mailimap_space_parse(fd, buffer, &cur_token);
3996 if (r != MAILIMAP_NO_ERROR) {
3997 res = r;
3998 goto sender;
3999 }
4000
4001 r = mailimap_env_reply_to_parse(fd, buffer, &cur_token, &reply_to,
4002 progr_rate, progr_fun);
4003 if (r != MAILIMAP_NO_ERROR) {
4004 res = r;
4005 goto sender;
4006 }
4007
4008 r = mailimap_space_parse(fd, buffer, &cur_token);
4009 if (r != MAILIMAP_NO_ERROR) {
4010 res = r;
4011 goto reply_to;
4012 }
4013
4014 r = mailimap_env_to_parse(fd, buffer, &cur_token, &to,
4015 progr_rate, progr_fun);
4016 if (r != MAILIMAP_NO_ERROR) {
4017 res = r;
4018 goto reply_to;
4019 }
4020
4021 r = mailimap_space_parse(fd, buffer, &cur_token);
4022 if (r != MAILIMAP_NO_ERROR) {
4023 res = r;
4024 goto to;
4025 }
4026
4027 r = mailimap_env_cc_parse(fd, buffer, &cur_token, &cc,
4028 progr_rate, progr_fun);
4029 if (r != MAILIMAP_NO_ERROR) {
4030 res = r;
4031 goto to;
4032 }
4033
4034 r = mailimap_space_parse(fd, buffer, &cur_token);
4035 if (r != MAILIMAP_NO_ERROR) {
4036 res = r;
4037 goto cc;
4038 }
4039
4040 r = mailimap_env_bcc_parse(fd, buffer, &cur_token, &bcc,
4041 progr_rate, progr_fun);
4042 if (r != MAILIMAP_NO_ERROR) {
4043 res = r;
4044 goto cc;
4045 }
4046
4047 r = mailimap_space_parse(fd, buffer, &cur_token);
4048 if (r != MAILIMAP_NO_ERROR) {
4049 res = r;
4050 goto bcc;
4051 }
4052
4053 r = mailimap_env_in_reply_to_parse(fd, buffer, &cur_token, &in_reply_to,
4054 progr_rate, progr_fun);
4055 if (r != MAILIMAP_NO_ERROR) {
4056 res = r;
4057 goto bcc;
4058 }
4059
4060 r = mailimap_space_parse(fd, buffer, &cur_token);
4061 if (r != MAILIMAP_NO_ERROR) {
4062 res = r;
4063 goto in_reply_to;
4064 }
4065
4066 r = mailimap_env_message_id_parse(fd, buffer, &cur_token, &message_id,
4067 progr_rate, progr_fun);
4068 if (r != MAILIMAP_NO_ERROR) {
4069 res = r;
4070 goto in_reply_to;
4071 }
4072
4073 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
4074 if (r != MAILIMAP_NO_ERROR) {
4075 res = r;
4076 goto message_id;
4077 }
4078
4079 envelope = mailimap_envelope_new(date, subject, from, sender, reply_to, to,
4080 cc, bcc, in_reply_to, message_id);
4081 if (envelope == NULL) {
4082 res = MAILIMAP_ERROR_MEMORY;
4083 goto message_id;
4084 }
4085
4086 * result = envelope;
4087 * index = cur_token;
4088
4089 return MAILIMAP_NO_ERROR;
4090
4091 message_id:
4092 mailimap_env_message_id_free(message_id);
4093 in_reply_to:
4094 mailimap_env_in_reply_to_free(in_reply_to);
4095 bcc:
4096 mailimap_env_bcc_free(bcc);
4097 cc:
4098 mailimap_env_cc_free(cc);
4099 to:
4100 mailimap_env_to_free(to);
4101 reply_to:
4102 mailimap_env_reply_to_free(reply_to);
4103 sender:
4104 mailimap_env_sender_free(sender);
4105 from:
4106 mailimap_env_from_free(from);
4107 subject:
4108 mailimap_env_subject_free(date);
4109 date:
4110 mailimap_env_date_free(date);
4111 err:
4112 return res;
4113}
4114
4115/*
4116 "(" 1*address ")"
4117*/
4118
4119static int mailimap_address_list_parse(mailstream * fd, MMAPString * buffer,
4120 size_t * index,
4121 clist ** result,
4122 size_t progr_rate,
4123 progress_function * progr_fun)
4124{
4125 size_t cur_token;
4126 clist * address_list;
4127 int r;
4128 int res;
4129
4130 cur_token = * index;
4131
4132 address_list = NULL;
4133
4134 r = mailimap_nil_parse(fd, buffer, &cur_token);
4135 switch (r) {
4136 case MAILIMAP_NO_ERROR:
4137 address_list = NULL;
4138 break;
4139
4140 case MAILIMAP_ERROR_PARSE:
4141 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
4142 if (r != MAILIMAP_NO_ERROR) {
4143 res = r;
4144 goto err;
4145 }
4146
4147 r = mailimap_struct_multiple_parse(fd, buffer, &cur_token, &address_list,
4148 (mailimap_struct_parser *)
4149 mailimap_address_parse,
4150 (mailimap_struct_destructor *)
4151 mailimap_address_free,
4152 progr_rate, progr_fun);
4153 if (r != MAILIMAP_NO_ERROR) {
4154 res = r;
4155 goto err;
4156 }
4157
4158 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
4159 if (r != MAILIMAP_NO_ERROR) {
4160 res = r;
4161 goto address_list;
4162 }
4163
4164 break;
4165
4166 default:
4167 res = r;
4168 goto err;
4169 }
4170
4171 * result = address_list;
4172 * index = cur_token;
4173
4174 return MAILIMAP_NO_ERROR;
4175
4176 address_list:
4177 if (address_list) {
4178 clist_foreach(address_list, (clist_func) mailimap_address_free, NULL);
4179 clist_free(address_list);
4180 }
4181 err:
4182 return res;
4183}
4184
4185/*
4186 env-bcc = "(" 1*address ")" / nil
4187*/
4188
4189static int
4190mailimap_env_bcc_parse(mailstream * fd, MMAPString * buffer,
4191 size_t * index, struct mailimap_env_bcc ** result,
4192 size_t progr_rate,
4193 progress_function * progr_fun)
4194{
4195 clist * list;
4196 size_t cur_token;
4197 struct mailimap_env_bcc * env_bcc;
4198 int r;
4199 int res;
4200
4201 cur_token = * index;
4202 list = NULL;
4203
4204 r = mailimap_address_list_parse(fd, buffer, &cur_token, &list,
4205 progr_rate, progr_fun);
4206 if (r != MAILIMAP_NO_ERROR) {
4207 res = r;
4208 goto err;
4209 }
4210
4211 env_bcc = mailimap_env_bcc_new(list);
4212 if (env_bcc == NULL) {
4213 res = MAILIMAP_ERROR_MEMORY;
4214 goto free;
4215 }
4216
4217 * index = cur_token;
4218 * result = env_bcc;
4219
4220 return MAILIMAP_NO_ERROR;
4221
4222 free:
4223 clist_foreach(list, (clist_func) mailimap_address_free, NULL);
4224 clist_free(list);
4225 err:
4226 return res;
4227}
4228
4229/*
4230 env-cc = "(" 1*address ")" / nil
4231*/
4232
4233static int
4234mailimap_env_cc_parse(mailstream * fd, MMAPString * buffer,
4235 size_t * index, struct mailimap_env_cc ** result,
4236 size_t progr_rate,
4237 progress_function * progr_fun)
4238{
4239 clist * list;
4240 size_t cur_token;
4241 struct mailimap_env_cc * env_cc;
4242 int r;
4243 int res;
4244
4245 cur_token = * index;
4246 list = NULL;
4247
4248 r = mailimap_address_list_parse(fd, buffer, &cur_token, &list,
4249 progr_rate, progr_fun);
4250 if (r != MAILIMAP_NO_ERROR) {
4251 res = r;
4252 goto err;
4253 }
4254
4255 env_cc = mailimap_env_cc_new(list);
4256 if (env_cc == NULL) {
4257 res = MAILIMAP_ERROR_MEMORY;
4258 goto free;
4259 }
4260
4261 * index = cur_token;
4262 * result = env_cc;
4263
4264 return MAILIMAP_NO_ERROR;
4265
4266 free:
4267 clist_foreach(list, (clist_func) mailimap_address_free, NULL);
4268 clist_free(list);
4269 err:
4270 return res;
4271}
4272
4273/*
4274 env-date = nstring
4275*/
4276
4277static int mailimap_env_date_parse(mailstream * fd, MMAPString * buffer,
4278 size_t * index, char ** result,
4279 size_t progr_rate,
4280 progress_function * progr_fun)
4281{
4282 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
4283 progr_rate, progr_fun);
4284}
4285
4286/*
4287 env-from = "(" 1*address ")" / nil
4288*/
4289
4290static int
4291mailimap_env_from_parse(mailstream * fd, MMAPString * buffer,
4292 size_t * index, struct mailimap_env_from ** result,
4293 size_t progr_rate,
4294 progress_function * progr_fun)
4295{
4296 clist * list;
4297 size_t cur_token;
4298 struct mailimap_env_from * env_from;
4299 int r;
4300 int res;
4301
4302 cur_token = * index;
4303 list = NULL;
4304
4305 r = mailimap_address_list_parse(fd, buffer, &cur_token, &list,
4306 progr_rate, progr_fun);
4307 if (r != MAILIMAP_NO_ERROR) {
4308 res = r;
4309 goto err;
4310 }
4311
4312 env_from = mailimap_env_from_new(list);
4313 if (env_from == NULL) {
4314 res = MAILIMAP_ERROR_MEMORY;
4315 goto free;
4316 }
4317
4318 * index = cur_token;
4319 * result = env_from;
4320
4321 return MAILIMAP_NO_ERROR;
4322
4323 free:
4324 clist_foreach(list, (clist_func) mailimap_address_free, NULL);
4325 clist_free(list);
4326 err:
4327 return res;
4328}
4329
4330/*
4331 env-in-reply-to = nstring
4332*/
4333
4334static int mailimap_env_in_reply_to_parse(mailstream * fd,
4335 MMAPString * buffer,
4336 size_t * index, char ** result,
4337 size_t progr_rate,
4338 progress_function * progr_fun)
4339{
4340 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
4341 progr_rate, progr_fun);
4342}
4343
4344/*
4345 env-message-id = nstring
4346*/
4347
4348static int mailimap_env_message_id_parse(mailstream * fd,
4349 MMAPString * buffer,
4350 size_t * index, char ** result,
4351 size_t progr_rate,
4352 progress_function * progr_fun)
4353{
4354 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
4355 progr_rate, progr_fun);
4356}
4357
4358/*
4359 env-reply-to = "(" 1*address ")" / nil
4360*/
4361
4362static int
4363mailimap_env_reply_to_parse(mailstream * fd, MMAPString * buffer,
4364 size_t * index,
4365 struct mailimap_env_reply_to ** result,
4366 size_t progr_rate,
4367 progress_function * progr_fun)
4368{
4369 clist * list;
4370 size_t cur_token;
4371 struct mailimap_env_reply_to * env_reply_to;
4372 int r;
4373 int res;
4374
4375 cur_token = * index;
4376 list = NULL;
4377
4378 r = mailimap_address_list_parse(fd, buffer, &cur_token, &list,
4379 progr_rate, progr_fun);
4380 if (r != MAILIMAP_NO_ERROR) {
4381 res = r;
4382 goto err;
4383 }
4384
4385 env_reply_to = mailimap_env_reply_to_new(list);
4386 if (env_reply_to == NULL) {
4387 res = MAILIMAP_ERROR_MEMORY;
4388 goto free;
4389 }
4390
4391 * index = cur_token;
4392 * result = env_reply_to;
4393
4394 return MAILIMAP_NO_ERROR;
4395
4396 free:
4397 clist_foreach(list, (clist_func) mailimap_address_free, NULL);
4398 clist_free(list);
4399 err:
4400 return res;
4401}
4402
4403/*
4404 env-sender = "(" 1*address ")" / nil
4405*/
4406
4407
4408static int
4409mailimap_env_sender_parse(mailstream * fd, MMAPString * buffer,
4410 size_t * index, struct mailimap_env_sender ** result,
4411 size_t progr_rate,
4412 progress_function * progr_fun)
4413{
4414 clist * list;
4415 size_t cur_token;
4416 struct mailimap_env_sender * env_sender;
4417 int r;
4418 int res;
4419
4420 cur_token = * index;
4421 list = NULL;
4422
4423 r = mailimap_address_list_parse(fd, buffer, &cur_token, &list,
4424 progr_rate, progr_fun);
4425 if (r != MAILIMAP_NO_ERROR) {
4426 res = r;
4427 goto err;
4428 }
4429
4430 env_sender = mailimap_env_sender_new(list);
4431 if (env_sender == NULL) {
4432 res = MAILIMAP_ERROR_MEMORY;
4433 goto free;
4434 }
4435
4436 * index = cur_token;
4437 * result = env_sender;
4438
4439 return MAILIMAP_NO_ERROR;
4440
4441 free:
4442 clist_foreach(list, (clist_func) mailimap_address_free, NULL);
4443 clist_free(list);
4444 err:
4445 return res;
4446}
4447
4448
4449/*
4450 env-subject = nstring
4451*/
4452
4453static int mailimap_env_subject_parse(mailstream * fd, MMAPString * buffer,
4454 size_t * index, char ** result,
4455 size_t progr_rate,
4456 progress_function * progr_fun)
4457{
4458 return mailimap_nstring_parse(fd, buffer, index, result, NULL,
4459 progr_rate, progr_fun);
4460}
4461
4462
4463/*
4464 env-to = "(" 1*address ")" / nil
4465*/
4466
4467static int mailimap_env_to_parse(mailstream * fd, MMAPString * buffer,
4468 size_t * index,
4469 struct mailimap_env_to ** result,
4470 size_t progr_rate,
4471 progress_function * progr_fun)
4472{
4473 clist * list;
4474 size_t cur_token;
4475 struct mailimap_env_to * env_to;
4476 int r;
4477 int res;
4478
4479 cur_token = * index;
4480 list = NULL;
4481
4482 r = mailimap_address_list_parse(fd, buffer, &cur_token, &list,
4483 progr_rate, progr_fun);
4484 if (r != MAILIMAP_NO_ERROR) {
4485 res = r;
4486 goto err;
4487 }
4488
4489 env_to = mailimap_env_to_new(list);
4490 if (env_to == NULL) {
4491 res = MAILIMAP_ERROR_MEMORY;
4492 goto free;
4493 }
4494
4495 * index = cur_token;
4496 * result = env_to;
4497
4498 return MAILIMAP_NO_ERROR;
4499
4500 free:
4501 clist_foreach(list, (clist_func) mailimap_address_free, NULL);
4502 clist_free(list);
4503 err:
4504 return res;
4505}
4506
4507
4508/*
4509 UNIMPLEMENTED
4510 examine = "EXAMINE" SP mailbox
4511*/
4512
4513/*
4514 UNIMPLEMENTED
4515 fetch = "FETCH" SP set SP ("ALL" / "FULL" / "FAST" / fetch-att /
4516 "(" fetch-att *(SP fetch-att) ")")
4517*/
4518
4519/*
4520 UNIMPLEMENTED
4521 fetch-att = "ENVELOPE" / "FLAGS" / "INTERNALDATE" /
4522 "RFC822" [".HEADER" / ".SIZE" / ".TEXT"] /
4523 "BODY" ["STRUCTURE"] / "UID" /
4524 "BODY" [".PEEK"] section ["<" number "." nz-number ">"]
4525*/
4526
4527/*
4528 flag = "\Answered" / "\Flagged" / "\Deleted" /
4529 "\Seen" / "\Draft" / flag-keyword / flag-extension
4530 ; Does not include "\Recent"
4531*/
4532
4533static int mailimap_flag_parse(mailstream * fd, MMAPString * buffer,
4534 size_t * index,
4535 struct mailimap_flag ** result,
4536 size_t progr_rate,
4537 progress_function * progr_fun)
4538{
4539 struct mailimap_flag * flag;
4540 size_t cur_token;
4541 char * flag_keyword;
4542 char * flag_extension;
4543 int type;
4544 int r;
4545 int res;
4546
4547 cur_token = * index;
4548
4549 flag_keyword = NULL;
4550 flag_extension = NULL;
4551
4552 type = mailimap_flag_get_token_value(fd, buffer, &cur_token);
4553 if (type == -1) {
4554 r = mailimap_flag_keyword_parse(fd, buffer, &cur_token, &flag_keyword,
4555 progr_rate, progr_fun);
4556 if (r == MAILIMAP_NO_ERROR)
4557 type = MAILIMAP_FLAG_KEYWORD;
4558
4559 if (r == MAILIMAP_ERROR_PARSE) {
4560 r = mailimap_flag_extension_parse(fd, buffer, &cur_token,
4561 &flag_extension,
4562 progr_rate, progr_fun);
4563 type = MAILIMAP_FLAG_EXTENSION;
4564 }
4565
4566 if (r != MAILIMAP_NO_ERROR) {
4567 res = r;
4568 goto err;
4569 }
4570 }
4571
4572 flag = mailimap_flag_new(type, flag_keyword, flag_extension);
4573 if (flag == NULL) {
4574 res = MAILIMAP_ERROR_MEMORY;
4575 goto free;
4576 }
4577
4578 * result = flag;
4579 * index = cur_token;
4580
4581 return MAILIMAP_NO_ERROR;
4582
4583 free:
4584 if (flag_keyword != NULL)
4585 mailimap_flag_keyword_free(flag_keyword);
4586 if (flag_extension != NULL)
4587 mailimap_flag_extension_free(flag_extension);
4588 err:
4589 return res;
4590}
4591
4592/*
4593 flag-extension = "\" atom
4594 ; Future expansion. Client implementations
4595 ; MUST accept flag-extension flags. Server
4596 ; implementations MUST NOT generate
4597 ; flag-extension flags except as defined by
4598 ; future standard or standards-track
4599 ; revisions of this specification.
4600*/
4601
4602static int mailimap_flag_extension_parse(mailstream * fd,
4603 MMAPString * buffer,
4604 size_t * index,
4605 char ** result,
4606 size_t progr_rate,
4607 progress_function * progr_fun)
4608{
4609 size_t cur_token;
4610 char * atom;
4611 int r;
4612
4613 cur_token = * index;
4614
4615 r = mailimap_char_parse(fd, buffer, &cur_token, '\\');
4616 if (r != MAILIMAP_NO_ERROR)
4617 return r;
4618
4619 r = mailimap_atom_parse(fd, buffer, &cur_token, &atom,
4620 progr_rate, progr_fun);
4621 if (r != MAILIMAP_NO_ERROR)
4622 return r;
4623
4624 * result = atom;
4625 * index = cur_token;
4626
4627 return MAILIMAP_NO_ERROR;
4628}
4629
4630/*
4631 flag-fetch = flag / "\Recent"
4632*/
4633
4634static int
4635mailimap_flag_fetch_parse(mailstream * fd, MMAPString * buffer,
4636 size_t * index,
4637 struct mailimap_flag_fetch ** result,
4638 size_t progr_rate,
4639 progress_function * progr_fun)
4640{
4641 size_t cur_token;
4642 struct mailimap_flag * flag;
4643 struct mailimap_flag_fetch * flag_fetch;
4644 int type;
4645 int r;
4646 int res;
4647
4648 cur_token = * index;
4649
4650 flag = NULL;
4651
4652 type = MAILIMAP_FLAG_FETCH_ERROR; /* XXX - removes a gcc warning */
4653
4654 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
4655 "\\Recent");
4656 if (r == MAILIMAP_NO_ERROR)
4657 type = MAILIMAP_FLAG_FETCH_RECENT;
4658
4659 if (r == MAILIMAP_ERROR_PARSE) {
4660 r = mailimap_flag_parse(fd, buffer, &cur_token, &flag,
4661 progr_rate, progr_fun);
4662 if (r == MAILIMAP_NO_ERROR)
4663 type = MAILIMAP_FLAG_FETCH_OTHER;
4664 }
4665
4666 if (r != MAILIMAP_NO_ERROR) {
4667 res = r;
4668 goto err;
4669 }
4670
4671 flag_fetch = mailimap_flag_fetch_new(type, flag);
4672 if (flag_fetch == NULL) {
4673 res = MAILIMAP_ERROR_MEMORY;
4674 goto free;
4675 }
4676
4677 * index = cur_token;
4678 * result = flag_fetch;
4679
4680 return MAILIMAP_NO_ERROR;
4681
4682 free:
4683 if (flag != NULL)
4684 mailimap_flag_free(flag);
4685 err:
4686 return res;
4687}
4688
4689/*
4690 flag-keyword = atom
4691*/
4692
4693static int mailimap_flag_keyword_parse(mailstream * fd, MMAPString * buffer,
4694 size_t * index,
4695 char ** result,
4696 size_t progr_rate,
4697 progress_function * progr_fun)
4698{
4699 return mailimap_atom_parse(fd, buffer, index, result,
4700 progr_rate, progr_fun);
4701}
4702
4703/*
4704 flag-list = "(" [flag *(SP flag)] ")"
4705*/
4706
4707static int mailimap_flag_list_parse(mailstream * fd, MMAPString * buffer,
4708 size_t * index,
4709 struct mailimap_flag_list ** result,
4710 size_t progr_rate,
4711 progress_function * progr_fun)
4712{
4713 size_t cur_token;
4714 clist * list;
4715 struct mailimap_flag_list * flag_list;
4716 int r;
4717 int res;
4718
4719 list = NULL;
4720 cur_token = * index;
4721
4722 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
4723 if (r != MAILIMAP_NO_ERROR) {
4724 res = r;
4725 goto err;
4726 }
4727
4728 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, &list,
4729 (mailimap_struct_parser *)
4730 mailimap_flag_parse,
4731 (mailimap_struct_destructor *)
4732 mailimap_flag_free,
4733 progr_rate, progr_fun);
4734
4735 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
4736 res = r;
4737 goto err;
4738 }
4739
4740 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
4741 if (r != MAILIMAP_NO_ERROR) {
4742 res = r;
4743 goto free;
4744 }
4745
4746 flag_list = mailimap_flag_list_new(list);
4747 if (flag_list == NULL) {
4748 res = MAILIMAP_ERROR_MEMORY;
4749 goto free;
4750 }
4751
4752 * result = flag_list;
4753 * index = cur_token;
4754
4755 return MAILIMAP_NO_ERROR;
4756
4757 free:
4758 if (list != NULL) {
4759 clist_foreach(list, (clist_func) mailimap_flag_free, NULL);
4760 clist_free(list);
4761 }
4762 err:
4763 return res;
4764}
4765
4766/*
4767 flag-perm = flag / "\*"
4768*/
4769
4770static int
4771mailimap_flag_perm_parse(mailstream * fd, MMAPString * buffer,
4772 size_t * index,
4773 struct mailimap_flag_perm ** result,
4774 size_t progr_rate,
4775 progress_function * progr_fun)
4776{
4777 size_t cur_token;
4778 struct mailimap_flag_perm * flag_perm;
4779 struct mailimap_flag * flag;
4780 int type;
4781 int r;
4782 int res;
4783
4784 flag = NULL;
4785 cur_token = * index;
4786 type = MAILIMAP_FLAG_PERM_ERROR; /* XXX - removes a gcc warning */
4787
4788 r = mailimap_flag_parse(fd, buffer, &cur_token, &flag,
4789 progr_rate, progr_fun);
4790 if (r == MAILIMAP_NO_ERROR)
4791 type = MAILIMAP_FLAG_PERM_FLAG;
4792
4793 if (r == MAILIMAP_ERROR_PARSE) {
4794 r = mailimap_token_case_insensitive_parse(fd, buffer,
4795 &cur_token, "\\*");
4796 if (r == MAILIMAP_NO_ERROR)
4797 type = MAILIMAP_FLAG_PERM_ALL;
4798 }
4799
4800 if (r != MAILIMAP_NO_ERROR) {
4801 res = r;
4802 goto err;
4803 }
4804
4805 flag_perm = mailimap_flag_perm_new(type, flag);
4806 if (flag_perm == NULL) {
4807 res = MAILIMAP_ERROR_MEMORY;
4808 goto free;
4809 }
4810
4811 * result = flag_perm;
4812 * index = cur_token;
4813
4814 return MAILIMAP_NO_ERROR;
4815
4816 free:
4817 if (flag != NULL)
4818 mailimap_flag_free(flag);
4819 err:
4820 return res;
4821}
4822
4823/*
4824 greeting = "*" SP (resp-cond-auth / resp-cond-bye) CRLF
4825*/
4826
4827int mailimap_greeting_parse(mailstream * fd, MMAPString * buffer,
4828 size_t * index,
4829 struct mailimap_greeting ** result,
4830 size_t progr_rate,
4831 progress_function * progr_fun)
4832{
4833 size_t cur_token;
4834 struct mailimap_resp_cond_auth * resp_cond_auth;
4835 struct mailimap_resp_cond_bye * resp_cond_bye;
4836 struct mailimap_greeting * greeting;
4837 int type;
4838 int r;
4839 int res;
4840
4841 cur_token = * index;
4842 resp_cond_bye = NULL;
4843 resp_cond_auth = NULL;
4844
4845 r = mailimap_star_parse(fd, buffer, &cur_token);
4846 if (r != MAILIMAP_NO_ERROR) {
4847 res = r;
4848 goto err;
4849 }
4850
4851 r = mailimap_space_parse(fd, buffer, &cur_token);
4852 if (r != MAILIMAP_NO_ERROR) {
4853 res = r;
4854 goto err;
4855 }
4856
4857 type = MAILIMAP_GREETING_RESP_COND_ERROR; /* XXX - removes a gcc warning */
4858
4859 r = mailimap_resp_cond_auth_parse(fd, buffer, &cur_token, &resp_cond_auth,
4860 progr_rate, progr_fun);
4861 if (r == MAILIMAP_NO_ERROR)
4862 type = MAILIMAP_GREETING_RESP_COND_AUTH;
4863
4864 if (r == MAILIMAP_ERROR_PARSE) {
4865 r = mailimap_resp_cond_bye_parse(fd, buffer, &cur_token,
4866 &resp_cond_bye,
4867 progr_rate, progr_fun);
4868 if (r == MAILIMAP_NO_ERROR)
4869 type = MAILIMAP_GREETING_RESP_COND_BYE;
4870 }
4871
4872 if (r != MAILIMAP_NO_ERROR) {
4873 res = r;
4874 goto err;
4875 }
4876
4877 r = mailimap_crlf_parse(fd, buffer, &cur_token);
4878 if (r != MAILIMAP_NO_ERROR) {
4879 res = r;
4880 goto free;
4881 }
4882
4883 greeting = mailimap_greeting_new(type, resp_cond_auth, resp_cond_bye);
4884 if (greeting == NULL) {
4885 res = MAILIMAP_ERROR_MEMORY;
4886 goto free;
4887 }
4888
4889 * result = greeting;
4890 * index = cur_token;
4891
4892 return MAILIMAP_NO_ERROR;
4893
4894 free:
4895 if (resp_cond_auth)
4896 mailimap_resp_cond_auth_free(resp_cond_auth);
4897 if (resp_cond_bye)
4898 mailimap_resp_cond_bye_free(resp_cond_bye);
4899 err:
4900 return res;
4901}
4902
4903/*
4904 header-fld-name = astring
4905*/
4906
4907static int
4908mailimap_header_fld_name_parse(mailstream * fd,
4909 MMAPString * buffer,
4910 size_t * index,
4911 char ** result,
4912 size_t progr_rate,
4913 progress_function * progr_fun)
4914{
4915 return mailimap_astring_parse(fd, buffer, index, result,
4916 progr_rate, progr_fun);
4917}
4918
4919/*
4920 header-list = "(" header-fld-name *(SP header-fld-name) ")"
4921*/
4922
4923static int
4924mailimap_header_list_parse(mailstream * fd, MMAPString * buffer,
4925 size_t * index,
4926 struct mailimap_header_list ** result,
4927 size_t progr_rate,
4928 progress_function * progr_fun)
4929{
4930 size_t cur_token;
4931 struct mailimap_header_list * header_list;
4932 clist * list;
4933 int r;
4934 int res;
4935
4936 cur_token = * index;
4937
4938 list = NULL;
4939
4940 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
4941 if (r != MAILIMAP_NO_ERROR) {
4942 res = r;
4943 goto err;
4944 }
4945
4946 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, &list,
4947 (mailimap_struct_parser *)
4948 mailimap_header_fld_name_parse,
4949 (mailimap_struct_destructor *)
4950 mailimap_header_fld_name_free,
4951 progr_rate, progr_fun);
4952 if (r != MAILIMAP_NO_ERROR) {
4953 res = r;
4954 goto err;
4955 }
4956
4957 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
4958 if (r != MAILIMAP_NO_ERROR) {
4959 res = r;
4960 goto free;
4961 }
4962
4963 header_list = mailimap_header_list_new(list);
4964 if (header_list == NULL) {
4965 res = MAILIMAP_ERROR_MEMORY;
4966 goto free;
4967 }
4968
4969 * result = header_list;
4970 * index = cur_token;
4971
4972 return MAILIMAP_NO_ERROR;
4973
4974 free:
4975 clist_foreach(list, (clist_func) mailimap_header_fld_name_free, NULL);
4976 clist_free(list);
4977 err:
4978 return res;
4979}
4980
4981/*
4982UNIMPLEMENTED
4983 list = "LIST" SP mailbox SP list-mailbox
4984
4985UNIMPLEMENTED
4986 list-mailbox = 1*list-char / string
4987
4988UNIMPLEMENTED
4989 list-char = ATOM-CHAR / list-wildcards / resp-specials
4990*/
4991
4992/*
4993 list-wildcards = "%" / "*"
4994*/
4995
4996static int is_list_wildcards(char ch)
4997{
4998 switch (ch) {
4999 case '%':
5000 case '*':
5001 return TRUE;
5002 }
5003 return FALSE;
5004}
5005
5006
5007/*
5008 literal = "{" number "}" CRLF *CHAR8
5009 ; Number represents the number of CHAR8s
5010*/
5011
5012static int mailimap_literal_parse(mailstream * fd, MMAPString * buffer,
5013 size_t * index, char ** result,
5014 size_t * result_len,
5015 size_t progr_rate,
5016 progress_function * progr_fun)
5017{
5018 size_t cur_token;
5019 uint32_t number;
5020 MMAPString * literal;
5021 char * literal_p;
5022 uint32_t left;
5023 int r;
5024 int res;
5025 size_t number_token;
5026
5027 cur_token = * index;
5028
5029 r = mailimap_oaccolade_parse(fd, buffer, &cur_token);
5030 if (r != MAILIMAP_NO_ERROR) {
5031 res = r;
5032 goto err;
5033 }
5034
5035 number_token = cur_token;
5036
5037 r = mailimap_number_parse(fd, buffer, &cur_token, &number);
5038 if (r != MAILIMAP_NO_ERROR) {
5039 res = r;
5040 goto err;
5041 }
5042
5043 r = mailimap_caccolade_parse(fd, buffer, &cur_token);
5044 if (r != MAILIMAP_NO_ERROR) {
5045 res = r;
5046 goto err;
5047 }
5048
5049 r = mailimap_crlf_parse(fd, buffer, &cur_token);
5050 if (r != MAILIMAP_NO_ERROR) {
5051 res = r;
5052 goto err;
5053 }
5054
5055 literal = mmap_string_sized_new(number);
5056 /*
5057 literal = g_new(char, number + 1);
5058 */
5059 if (literal == NULL) {
5060 res = MAILIMAP_ERROR_MEMORY;
5061 goto err;
5062 }
5063
5064 left = buffer->len - cur_token;
5065
5066 if (left >= number) {
5067 /*
5068 if (number > 0)
5069 strncpy(literal, buffer->str + cur_token, number);
5070 literal[number] = 0;
5071 */
5072 if (number > 0)
5073 if (mmap_string_append_len(literal, buffer->str + cur_token,
5074 number) == NULL) {
5075 res = MAILIMAP_ERROR_MEMORY;
5076 goto free_literal;
5077 }
5078 if ((progr_fun != NULL) && (progr_rate != 0))
5079 progr_fun(number, number);
5080
5081 cur_token = cur_token + number;
5082 }
5083 else {
5084 uint32_t needed;
5085 uint32_t current_prog = 0;
5086 uint32_t last_prog = 0;
5087
5088 needed = number - left;
5089 memcpy(literal->str, buffer->str + cur_token, left);
5090 literal->len += left;
5091 literal_p = literal->str + left;
5092 current_prog = left;
5093
5094 while (needed > 0) {
5095 ssize_t read_bytes;
5096
5097 read_bytes = mailstream_read(fd, literal_p, needed);
5098 if (read_bytes == -1) {
5099 res = MAILIMAP_ERROR_STREAM;
5100 goto free_literal;
5101 }
5102 literal->len += read_bytes;
5103 needed -= read_bytes;
5104 literal_p += read_bytes;
5105
5106 current_prog += read_bytes;
5107 if ((progr_fun != NULL) && (progr_rate != 0))
5108 if (current_prog - last_prog > progr_rate) {
5109 progr_fun(current_prog, number);
5110 last_prog = current_prog;
5111 }
5112 }
5113
5114 literal->str[number] = 0;
5115
5116#if 0
5117 literal->str[number] = 0;
5118 if (mmap_string_append_len(buffer, literal->str + left,
5119 literal->len - left) == NULL) {
5120 res = MAILIMAP_ERROR_STREAM;
5121 goto free_literal;
5122 }
5123#endif
5124
5125 if (mmap_string_truncate(buffer, number_token) == NULL) {
5126 res = MAILIMAP_ERROR_MEMORY;
5127 goto free_literal;
5128 }
5129
5130 if (mmap_string_append(buffer, "0}\r\n") == NULL) {
5131 res = MAILIMAP_ERROR_MEMORY;
5132 goto free_literal;
5133 }
5134
5135 cur_token = number_token + 4;
5136 }
5137 if ((progr_fun != NULL) && (progr_rate != 0))
5138 progr_fun(number, number);
5139
5140 if (mailstream_read_line_append(fd, buffer) == NULL) {
5141 res = MAILIMAP_ERROR_STREAM;
5142 goto free_literal;
5143 }
5144
5145 if (mmap_string_ref(literal) < 0) {
5146 res = MAILIMAP_ERROR_MEMORY;
5147 goto free_literal;
5148 }
5149
5150 * result = literal->str;
5151 if (result_len != NULL)
5152 * result_len = literal->len;
5153 * index = cur_token;
5154
5155 return MAILIMAP_NO_ERROR;
5156
5157 free_literal:
5158 mmap_string_free(literal);
5159 err:
5160 return res;
5161}
5162
5163/*
5164 UNIMPLEMENTED
5165 login = "LOGIN" SP userid SP password
5166
5167 UNIMPLEMENTED
5168 lsub = "LSUB" SP mailbox SP list-mailbox
5169*/
5170
5171/*
5172 mailbox = "INBOX" / astring
5173 ; INBOX is case-insensitive. All case variants of
5174 ; INBOX (e.g. "iNbOx") MUST be interpreted as INBOX
5175 ; not as an astring. An astring which consists of
5176 ; the case-insensitive sequence "I" "N" "B" "O" "X"
5177 ; is considered to be INBOX and not an astring.
5178 ; Refer to section 5.1 for further
5179 ; semantic details of mailbox names.
5180*/
5181
5182static int
5183mailimap_mailbox_parse(mailstream * fd, MMAPString * buffer,
5184 size_t * index, char ** result,
5185 size_t progr_rate,
5186 progress_function * progr_fun)
5187{
5188 size_t cur_token;
5189 char * name;
5190 int r;
5191
5192 cur_token = * index;
5193
5194 r = mailimap_astring_parse(fd, buffer, &cur_token, &name,
5195 progr_rate, progr_fun);
5196 if (r != MAILIMAP_NO_ERROR)
5197 return r;
5198
5199 * result = name;
5200 * index = cur_token;
5201
5202 return MAILIMAP_NO_ERROR;
5203}
5204
5205
5206/*
5207 mailbox-data = "FLAGS" SP flag-list / "LIST" SP mailbox-list /
5208 "LSUB" SP mailbox-list / "SEARCH" *(SP nz-number) /
5209 "STATUS" SP mailbox SP "("
5210 [status-att SP number *(SP status-att SP number)] ")" /
5211 number SP "EXISTS" / number SP "RECENT"
5212*/
5213
5214/*
5215 "FLAGS" SP flag-list
5216*/
5217
5218static int
5219mailimap_mailbox_data_flags_parse(mailstream * fd, MMAPString * buffer,
5220 size_t * index,
5221 struct mailimap_flag_list ** result,
5222 size_t progr_rate,
5223 progress_function * progr_fun)
5224{
5225 size_t cur_token;
5226 struct mailimap_flag_list * flag_list;
5227 int r;
5228
5229 cur_token = * index;
5230
5231 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "FLAGS");
5232 if (r != MAILIMAP_NO_ERROR)
5233 return r;
5234
5235 r = mailimap_space_parse(fd, buffer, &cur_token);
5236 if (r != MAILIMAP_NO_ERROR)
5237 return r;
5238
5239 r = mailimap_flag_list_parse(fd, buffer, &cur_token, &flag_list,
5240 progr_rate, progr_fun);
5241 if (r != MAILIMAP_NO_ERROR)
5242 return r;
5243
5244 * result = flag_list;
5245 * index = cur_token;
5246
5247 return MAILIMAP_NO_ERROR;
5248}
5249
5250
5251/*
5252 "LIST" SP mailbox-list
5253*/
5254
5255static int
5256mailimap_mailbox_data_list_parse(mailstream * fd, MMAPString * buffer,
5257 size_t * index,
5258 struct mailimap_mailbox_list ** result,
5259 size_t progr_rate,
5260 progress_function * progr_fun)
5261{
5262 size_t cur_token;
5263 struct mailimap_mailbox_list * mb_list;
5264 int r;
5265 int res;
5266
5267 cur_token = * index;
5268
5269 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "LIST");
5270 if (r != MAILIMAP_NO_ERROR) {
5271 res = r;
5272 return r;
5273 }
5274
5275 r = mailimap_space_parse(fd, buffer, &cur_token);
5276 if (r != MAILIMAP_NO_ERROR) {
5277 res = r;
5278 return r;
5279 }
5280
5281 r = mailimap_mailbox_list_parse(fd, buffer, &cur_token, &mb_list,
5282 progr_rate, progr_fun);
5283 if (r != MAILIMAP_NO_ERROR) {
5284 res = r;
5285 return r;
5286 }
5287
5288 * result = mb_list;
5289 * index = cur_token;
5290
5291 return MAILIMAP_NO_ERROR;
5292}
5293
5294/*
5295 "LSUB" SP mailbox-list
5296*/
5297
5298static int
5299mailimap_mailbox_data_lsub_parse(mailstream * fd, MMAPString * buffer,
5300 size_t * index,
5301 struct mailimap_mailbox_list ** result,
5302 size_t progr_rate,
5303 progress_function * progr_fun)
5304{
5305 size_t cur_token;
5306 struct mailimap_mailbox_list * mb_list;
5307 int r;
5308
5309 cur_token = * index;
5310
5311 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "LSUB");
5312 if (r != MAILIMAP_NO_ERROR)
5313 return r;
5314
5315 r = mailimap_space_parse(fd, buffer, &cur_token);
5316 if (r != MAILIMAP_NO_ERROR)
5317 return r;
5318
5319 r = mailimap_mailbox_list_parse(fd, buffer, &cur_token, &mb_list,
5320 progr_rate, progr_fun);
5321 if (r != MAILIMAP_NO_ERROR)
5322 return r;
5323
5324 * result = mb_list;
5325 * index = cur_token;
5326
5327 return MAILIMAP_NO_ERROR;
5328}
5329
5330/*
5331 "SEARCH" *(SP nz-number)
5332*/
5333
5334
5335static int
5336mailimap_mailbox_data_search_parse(mailstream * fd, MMAPString * buffer,
5337 size_t * index,
5338 clist ** result,
5339 size_t progr_rate,
5340 progress_function * progr_fun)
5341{
5342 size_t cur_token;
5343 size_t final_token;
5344 clist * number_list;
5345 int r;
5346
5347 cur_token = * index;
5348
5349 r = mailimap_token_case_insensitive_parse(fd, buffer,
5350 &cur_token, "SEARCH");
5351 if (r != MAILIMAP_NO_ERROR)
5352 return r;
5353
5354 final_token = cur_token;
5355 number_list = NULL;
5356
5357 r = mailimap_space_parse(fd, buffer, &cur_token);
5358 if (r == MAILIMAP_NO_ERROR) {
5359 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, &number_list,
5360 (mailimap_struct_parser *)
5361 mailimap_nz_number_alloc_parse,
5362 (mailimap_struct_destructor *)
5363 mailimap_number_alloc_free,
5364 progr_rate, progr_fun);
5365 if (r == MAILIMAP_NO_ERROR)
5366 final_token = cur_token;
5367 }
5368
5369 * result = number_list;
5370 * index = final_token;
5371
5372 return MAILIMAP_NO_ERROR;
5373}
5374
5375/*
5376 "STATUS" SP mailbox SP "("
5377 [status-att SP number *(SP status-att SP number)] ")"
5378*/
5379
5380/*
5381 status-att SP number
5382*/
5383
5384static int
5385mailimap_status_info_parse(mailstream * fd, MMAPString * buffer,
5386 size_t * index,
5387 struct mailimap_status_info **
5388 result,
5389 size_t progr_rate,
5390 progress_function * progr_fun)
5391{
5392 size_t cur_token;
5393 int status_att;
5394 uint32_t value;
5395 struct mailimap_status_info * info;
5396 int r;
5397
5398 cur_token = * index;
5399 value = 0;
5400
5401 r = mailimap_status_att_parse(fd, buffer, &cur_token, &status_att);
5402 if (r != MAILIMAP_NO_ERROR)
5403 return r;
5404
5405 r = mailimap_space_parse(fd, buffer, &cur_token);
5406 if (r != MAILIMAP_NO_ERROR)
5407 return r;
5408
5409 r = mailimap_number_parse(fd, buffer, &cur_token, &value);
5410 if (r != MAILIMAP_NO_ERROR)
5411 return r;
5412
5413 info = mailimap_status_info_new(status_att, value);
5414 if (info == NULL)
5415 return MAILIMAP_ERROR_MEMORY;
5416
5417 * result = info;
5418 * index = cur_token;
5419
5420 return MAILIMAP_NO_ERROR;
5421}
5422
5423/*
5424 "STATUS" SP mailbox SP "("
5425 [status-att SP number *(SP status-att SP number)] ")"
5426*/
5427
5428static int
5429mailimap_mailbox_data_status_parse(mailstream * fd, MMAPString * buffer,
5430 size_t * index, struct
5431 mailimap_mailbox_data_status ** result,
5432 size_t progr_rate,
5433 progress_function * progr_fun)
5434{
5435 size_t cur_token;
5436 char * mb;
5437 clist * status_info_list;
5438 struct mailimap_mailbox_data_status * data_status;
5439 int r;
5440 int res;
5441
5442 cur_token = * index;
5443 mb = NULL;
5444 status_info_list = NULL;
5445
5446 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "STATUS");
5447 if (r != MAILIMAP_NO_ERROR) {
5448 res = r;
5449 goto err;
5450 }
5451
5452 r = mailimap_space_parse(fd, buffer, &cur_token);
5453 if (r != MAILIMAP_NO_ERROR) {
5454 res = r;
5455 goto err;
5456 }
5457
5458 r = mailimap_mailbox_parse(fd, buffer, &cur_token, &mb,
5459 progr_rate, progr_fun);
5460 if (r != MAILIMAP_NO_ERROR) {
5461 res = r;
5462 goto err;
5463 }
5464
5465 r = mailimap_space_parse(fd, buffer, &cur_token);
5466 if (r != MAILIMAP_NO_ERROR) {
5467 res = r;
5468 goto mailbox;
5469 }
5470
5471 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
5472 if (r != MAILIMAP_NO_ERROR) {
5473 res = r;
5474 goto mailbox;
5475 }
5476
5477 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token,
5478 &status_info_list,
5479 (mailimap_struct_parser *)
5480 mailimap_status_info_parse,
5481 (mailimap_struct_destructor *)
5482 mailimap_status_info_free,
5483 progr_rate, progr_fun);
5484 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
5485 res = r;
5486 goto mailbox;
5487 }
5488
5489 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
5490 if (r != MAILIMAP_NO_ERROR) {
5491 res = r;
5492 goto status_info_list;
5493 }
5494
5495 data_status = mailimap_mailbox_data_status_new(mb, status_info_list);
5496 if (data_status == NULL) {
5497 res = MAILIMAP_ERROR_MEMORY;
5498 goto status_info_list;
5499 }
5500
5501 * result = data_status;
5502 * index = cur_token;
5503
5504 return MAILIMAP_NO_ERROR;
5505
5506 status_info_list:
5507 if (status_info_list != NULL) {
5508 clist_foreach(status_info_list, (clist_func) mailimap_status_info_free,
5509 NULL);
5510 clist_free(status_info_list);
5511 }
5512 mailbox:
5513 mailimap_mailbox_free(mb);
5514 err:
5515 return res;
5516}
5517
5518/*
5519 number SP "EXISTS"
5520*/
5521
5522static int
5523mailimap_mailbox_data_exists_parse(mailstream * fd, MMAPString * buffer,
5524 size_t * index,
5525 uint32_t * result)
5526{
5527 size_t cur_token;
5528 uint32_t number;
5529 int r;
5530
5531 cur_token = * index;
5532
5533 r = mailimap_number_parse(fd, buffer, &cur_token, &number);
5534 if (r != MAILIMAP_NO_ERROR)
5535 return r;
5536
5537 r = mailimap_space_parse(fd, buffer, &cur_token);
5538 if (r != MAILIMAP_NO_ERROR)
5539 return r;
5540
5541 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "EXISTS");
5542 if (r != MAILIMAP_NO_ERROR)
5543 return r;
5544
5545 * result = number;
5546 * index = cur_token;
5547
5548 return MAILIMAP_NO_ERROR;
5549}
5550
5551/*
5552 number SP "RECENT"
5553*/
5554
5555static int
5556mailimap_mailbox_data_recent_parse(mailstream * fd, MMAPString * buffer,
5557 size_t * index,
5558 uint32_t * result)
5559{
5560 size_t cur_token;
5561 uint32_t number;
5562 int r;
5563
5564 cur_token = * index;
5565
5566 r = mailimap_number_parse(fd, buffer, &cur_token, &number);
5567 if (r != MAILIMAP_NO_ERROR)
5568 return r;
5569
5570 r = mailimap_space_parse(fd, buffer, &cur_token);
5571 if (r != MAILIMAP_NO_ERROR)
5572 return r;
5573
5574 r = mailimap_token_case_insensitive_parse(fd, buffer,
5575 &cur_token, "RECENT");
5576 if (r != MAILIMAP_NO_ERROR)
5577 return r;
5578
5579 * result = number;
5580 * index = cur_token;
5581
5582 return MAILIMAP_NO_ERROR;
5583}
5584
5585/*
5586 mailbox-data = "FLAGS" SP flag-list / "LIST" SP mailbox-list /
5587 "LSUB" SP mailbox-list / "SEARCH" *(SP nz-number) /
5588 "STATUS" SP mailbox SP "("
5589 [status-att SP number *(SP status-att SP number)] ")" /
5590 number SP "EXISTS" / number SP "RECENT"
5591*/
5592
5593static int
5594mailimap_mailbox_data_parse(mailstream * fd, MMAPString * buffer,
5595 size_t * index,
5596 struct mailimap_mailbox_data ** result,
5597 size_t progr_rate,
5598 progress_function * progr_fun)
5599{
5600 int type;
5601 struct mailimap_flag_list * data_flags;
5602 struct mailimap_mailbox_list * data_list;
5603 struct mailimap_mailbox_list * data_lsub;
5604 clist * data_search;
5605 struct mailimap_mailbox_data_status * data_status;
5606 uint32_t data_exists;
5607 uint32_t data_recent;
5608
5609 struct mailimap_mailbox_data * mailbox_data;
5610 size_t cur_token;
5611 int r;
5612 int res;
5613
5614 cur_token = * index;
5615
5616 data_flags = NULL;
5617 data_list = NULL;
5618 data_lsub = NULL;
5619 data_search = NULL;
5620 data_status = NULL;
5621 data_exists = 0;
5622 data_recent = 0;
5623
5624 type = MAILIMAP_MAILBOX_DATA_ERROR; /* XXX - removes a gcc warning */
5625
5626 r = mailimap_mailbox_data_flags_parse(fd, buffer, &cur_token,
5627 &data_flags,
5628 progr_rate, progr_fun);
5629 if (r == MAILIMAP_NO_ERROR)
5630 type = MAILIMAP_MAILBOX_DATA_FLAGS;
5631
5632 if (r == MAILIMAP_ERROR_PARSE) {
5633 r = mailimap_mailbox_data_list_parse(fd, buffer, &cur_token,
5634 &data_list,
5635 progr_rate, progr_fun);
5636 if (r == MAILIMAP_NO_ERROR)
5637 type = MAILIMAP_MAILBOX_DATA_LIST;
5638 }
5639
5640 if (r == MAILIMAP_ERROR_PARSE) {
5641 r = mailimap_mailbox_data_lsub_parse(fd, buffer, &cur_token,
5642 &data_lsub,
5643 progr_rate, progr_fun);
5644 if (r == MAILIMAP_NO_ERROR)
5645 type = MAILIMAP_MAILBOX_DATA_LSUB;
5646 }
5647
5648 if (r == MAILIMAP_ERROR_PARSE) {
5649 r = mailimap_mailbox_data_search_parse(fd, buffer, &cur_token,
5650 &data_search,
5651 progr_rate, progr_fun);
5652 if (r == MAILIMAP_NO_ERROR)
5653 type = MAILIMAP_MAILBOX_DATA_SEARCH;
5654 }
5655
5656 if (r == MAILIMAP_ERROR_PARSE) {
5657 r = mailimap_mailbox_data_status_parse(fd, buffer, &cur_token,
5658 &data_status,
5659 progr_rate, progr_fun);
5660 if (r == MAILIMAP_NO_ERROR)
5661 type = MAILIMAP_MAILBOX_DATA_STATUS;
5662 }
5663
5664 if (r == MAILIMAP_ERROR_PARSE) {
5665 r = mailimap_mailbox_data_exists_parse(fd, buffer, &cur_token,
5666 &data_exists);
5667 if (r == MAILIMAP_NO_ERROR)
5668 type = MAILIMAP_MAILBOX_DATA_EXISTS;
5669 }
5670
5671 if (r == MAILIMAP_ERROR_PARSE) {
5672 r = mailimap_mailbox_data_recent_parse(fd, buffer, &cur_token,
5673 &data_recent);
5674 if (r == MAILIMAP_NO_ERROR)
5675 type = MAILIMAP_MAILBOX_DATA_RECENT;
5676 }
5677
5678 if (r != MAILIMAP_NO_ERROR) {
5679 res = r;
5680 goto err;
5681 }
5682
5683 mailbox_data = mailimap_mailbox_data_new(type, data_flags, data_list,
5684 data_lsub, data_search,
5685 data_status,
5686 data_exists, data_recent);
5687
5688 if (mailbox_data == NULL) {
5689 res = MAILIMAP_ERROR_MEMORY;
5690 goto free;
5691 }
5692
5693 * result = mailbox_data;
5694 * index = cur_token;
5695
5696 return MAILIMAP_NO_ERROR;
5697
5698 free:
5699 if (data_flags != NULL)
5700 mailimap_flag_list_free(data_flags);
5701 if (data_list != NULL)
5702 mailimap_mailbox_list_free(data_list);
5703 if (data_lsub != NULL)
5704 mailimap_mailbox_list_free(data_lsub);
5705 if (data_search != NULL)
5706 mailimap_mailbox_data_search_free(data_search);
5707 if (data_status != NULL)
5708 mailimap_mailbox_data_status_free(data_status);
5709 err:
5710 return res;
5711}
5712
5713/*
5714 mailbox-list = "(" [mbx-list-flags] ")" SP
5715 (DQUOTE QUOTED-CHAR DQUOTE / nil) SP mailbox
5716*/
5717
5718/*
5719 DQUOTE QUOTED-CHAR DQUOTE
5720*/
5721
5722static int
5723mailimap_mailbox_list_quoted_char_parse(mailstream * fd, MMAPString * buffer,
5724 size_t * index,
5725 char * result)
5726{
5727 size_t cur_token;
5728 char ch;
5729 int r;
5730
5731 cur_token = * index;
5732
5733 r = mailimap_dquote_parse(fd, buffer, &cur_token);
5734 if (r != MAILIMAP_NO_ERROR)
5735 return r;
5736
5737 r = mailimap_quoted_char_parse(fd, buffer, &cur_token, &ch);
5738 if (r != MAILIMAP_NO_ERROR)
5739 return r;
5740
5741 r = mailimap_dquote_parse(fd, buffer, &cur_token);
5742 if (r != MAILIMAP_NO_ERROR)
5743 return r;
5744
5745 * index = cur_token;
5746 * result = ch;
5747
5748 return MAILIMAP_NO_ERROR;
5749}
5750
5751static int
5752mailimap_mailbox_list_parse(mailstream * fd, MMAPString * buffer,
5753 size_t * index,
5754 struct mailimap_mailbox_list ** result,
5755 size_t progr_rate,
5756 progress_function * progr_fun)
5757{
5758 struct mailimap_mailbox_list * mb_list;
5759 struct mailimap_mbx_list_flags * mb_flag_list;
5760 char ch;
5761 char * mb;
5762 size_t cur_token;
5763 int r;
5764 int res;
5765
5766 cur_token = * index;
5767
5768 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
5769 if (r != MAILIMAP_NO_ERROR) {
5770 res = r;
5771 goto err;
5772 }
5773
5774 mb_flag_list = NULL;
5775 ch = 0;
5776 mb = NULL;
5777
5778 r = mailimap_mbx_list_flags_parse(fd, buffer, &cur_token,
5779 &mb_flag_list, progr_rate, progr_fun);
5780 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
5781 res = r;
5782 goto err;
5783 }
5784
5785 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
5786 if (r != MAILIMAP_NO_ERROR) {
5787 res = r;
5788 goto free_list_flags;
5789 }
5790
5791 r = mailimap_space_parse(fd, buffer, &cur_token);
5792 if (r != MAILIMAP_NO_ERROR) {
5793 res = r;
5794 goto free_list_flags;
5795 }
5796
5797 r = mailimap_mailbox_list_quoted_char_parse(fd, buffer, &cur_token, &ch);
5798 if (r == MAILIMAP_ERROR_PARSE)
5799 r = mailimap_nil_parse(fd, buffer, &cur_token);
5800
5801 if (r != MAILIMAP_NO_ERROR) {
5802 res = r;
5803 goto free_list_flags;
5804 }
5805
5806 r = mailimap_space_parse(fd, buffer, &cur_token);
5807 if (r != MAILIMAP_NO_ERROR) {
5808 res = r;
5809 goto free_list_flags;
5810 }
5811
5812 r = mailimap_mailbox_parse(fd, buffer, &cur_token, &mb,
5813 progr_rate, progr_fun);
5814 if (r != MAILIMAP_NO_ERROR) {
5815 res = r;
5816 goto free_list_flags;
5817 }
5818
5819 mb_list = mailimap_mailbox_list_new(mb_flag_list, ch, mb);
5820 if (mb_list == NULL) {
5821 res = MAILIMAP_ERROR_MEMORY;
5822 goto free_mailbox;
5823 }
5824
5825 * result = mb_list;
5826 * index = cur_token;
5827
5828 return MAILIMAP_NO_ERROR;
5829
5830 free_mailbox:
5831 mailimap_mailbox_free(mb);
5832 free_list_flags:
5833 if (mb_flag_list != NULL)
5834 mailimap_mbx_list_flags_free(mb_flag_list);
5835 err:
5836 return res;
5837}
5838
5839/*
5840 mbx-list-flags = *(mbx-list-oflag SP) mbx-list-sflag
5841 *(SP mbx-list-oflag) /
5842 mbx-list-oflag *(SP mbx-list-oflag)
5843*/
5844
5845static int
5846mailimap_mbx_list_flags_parse(mailstream * fd, MMAPString * buffer,
5847 size_t * index,
5848 struct mailimap_mbx_list_flags ** result,
5849 size_t progr_rate,
5850 progress_function * progr_fun)
5851{
5852 struct mailimap_mbx_list_flags * mbx_list_flag;
5853 size_t cur_token;
5854 clist * oflags;
5855 clist * oflags_2;
5856 int sflag;
5857 int type;
5858 int r;
5859 int res;
5860 size_t final_token;
5861 int try_sflag;
5862
5863 cur_token = * index;
5864 final_token = cur_token;
5865
5866 oflags = clist_new();
5867 if (oflags == NULL) {
5868 res = MAILIMAP_ERROR_MEMORY;
5869 goto err;
5870 }
5871
5872 sflag = MAILIMAP_MBX_LIST_SFLAG_ERROR;
5873 oflags_2 = NULL;
5874
5875 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token,
5876 &oflags_2,
5877 (mailimap_struct_parser *)
5878 mailimap_mbx_list_oflag_no_sflag_parse,
5879 (mailimap_struct_destructor *)
5880 mailimap_mbx_list_oflag_free,
5881 progr_rate, progr_fun);
5882 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
5883 res = r;
5884 goto free;
5885 }
5886
5887 try_sflag = 1;
5888 if (r == MAILIMAP_NO_ERROR) {
5889 clist_concat(oflags, oflags_2);
5890 clist_free(oflags_2);
5891
5892 final_token = cur_token;
5893 try_sflag = 0;
5894 r = mailimap_space_parse(fd, buffer, &cur_token);
5895 if (r == MAILIMAP_NO_ERROR)
5896 try_sflag = 1;
5897 }
5898
5899 type = MAILIMAP_MBX_LIST_FLAGS_NO_SFLAG;
5900 if (try_sflag) {
5901 r = mailimap_mbx_list_sflag_parse(fd, buffer, &cur_token, &sflag);
5902 switch (r) {
5903 case MAILIMAP_ERROR_PARSE:
5904 type = MAILIMAP_MBX_LIST_FLAGS_NO_SFLAG;
5905 break;
5906
5907 case MAILIMAP_NO_ERROR:
5908 type = MAILIMAP_MBX_LIST_FLAGS_SFLAG;
5909
5910 final_token = cur_token;
5911 r = mailimap_space_parse(fd, buffer, &cur_token);
5912 if (r == MAILIMAP_NO_ERROR) {
5913 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token,
5914 &oflags_2,
5915 (mailimap_struct_parser *) mailimap_mbx_list_oflag_parse,
5916 (mailimap_struct_destructor *) mailimap_mbx_list_oflag_free,
5917 progr_rate, progr_fun);
5918 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
5919 res = r;
5920 goto err;
5921 }
5922
5923 if (r == MAILIMAP_NO_ERROR) {
5924 clist_concat(oflags, oflags_2);
5925 clist_free(oflags_2);
5926
5927 final_token = cur_token;
5928 }
5929 }
5930
5931 break;
5932
5933 default:
5934 res = r;
5935 goto free;
5936 }
5937 }
5938
5939 if ((clist_count(oflags) == 0) && (type == MAILIMAP_MBX_LIST_FLAGS_NO_SFLAG)) {
5940 res = MAILIMAP_ERROR_PARSE;
5941 goto free;
5942 }
5943
5944 cur_token = final_token;
5945 mbx_list_flag = mailimap_mbx_list_flags_new(type, oflags, sflag);
5946 if (mbx_list_flag == NULL) {
5947 res = MAILIMAP_ERROR_MEMORY;
5948 goto free;
5949 }
5950
5951 * result = mbx_list_flag;
5952 * index = cur_token;
5953
5954 return MAILIMAP_NO_ERROR;
5955
5956free:
5957 clist_foreach(oflags, (clist_func) mailimap_mbx_list_oflag_free, NULL);
5958 clist_free(oflags);
5959err:
5960 return res;
5961}
5962
5963/*
5964 mbx-list-oflag = "\Noinferiors" / flag-extension
5965 ; Other flags; multiple possible per LIST response
5966*/
5967
5968static int
5969mailimap_mbx_list_oflag_parse(mailstream * fd, MMAPString * buffer,
5970 size_t * index,
5971 struct mailimap_mbx_list_oflag ** result,
5972 size_t progr_rate,
5973 progress_function * progr_fun)
5974{
5975 int type;
5976 size_t cur_token;
5977 struct mailimap_mbx_list_oflag * oflag;
5978 char * flag_ext;
5979 int r;
5980 int res;
5981 int sflag_type;
5982
5983 cur_token = * index;
5984 flag_ext = NULL;
5985 type = MAILIMAP_MBX_LIST_OFLAG_ERROR; /* XXX - removes a gcc warning */
5986
5987 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
5988 "\\Noinferiors");
5989 if (r == MAILIMAP_NO_ERROR)
5990 type = MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS;
5991
5992 if (r == MAILIMAP_ERROR_PARSE) {
5993 r = mailimap_flag_extension_parse(fd, buffer, &cur_token,
5994 &flag_ext, progr_rate, progr_fun);
5995 if (r == MAILIMAP_NO_ERROR)
5996 type = MAILIMAP_MBX_LIST_OFLAG_FLAG_EXT;
5997 }
5998
5999 if (r != MAILIMAP_NO_ERROR) {
6000 res = r;
6001 goto err;
6002 }
6003
6004 oflag = mailimap_mbx_list_oflag_new(type, flag_ext);
6005 if (oflag == NULL) {
6006 res = MAILIMAP_ERROR_MEMORY;
6007 goto free;
6008 }
6009
6010 * result = oflag;
6011 * index = cur_token;
6012
6013 return MAILIMAP_NO_ERROR;
6014
6015 free:
6016 if (flag_ext != NULL)
6017 mailimap_flag_extension_free(flag_ext);
6018 err:
6019 return res;
6020}
6021
6022static int
6023mailimap_mbx_list_oflag_no_sflag_parse(mailstream * fd, MMAPString * buffer,
6024 size_t * index,
6025 struct mailimap_mbx_list_oflag ** result,
6026 size_t progr_rate,
6027 progress_function * progr_fun)
6028{
6029 size_t cur_token;
6030 int sflag_type;
6031 int r;
6032
6033 cur_token = * index;
6034
6035 r = mailimap_mbx_list_sflag_parse(fd, buffer, &cur_token, &sflag_type);
6036 if (r == MAILIMAP_NO_ERROR)
6037 return MAILIMAP_ERROR_PARSE;
6038
6039 return mailimap_mbx_list_oflag_parse(fd, buffer, index, result,
6040 progr_rate, progr_fun);
6041}
6042
6043
6044/*
6045 mbx-list-sflag = "\Noselect" / "\Marked" / "\Unmarked"
6046 ; Selectability flags; only one per LIST response
6047*/
6048
6049static int
6050mailimap_mbx_list_sflag_parse(mailstream * fd, MMAPString * buffer,
6051 size_t * index,
6052 int * result)
6053{
6054 int type;
6055 size_t cur_token;
6056
6057 cur_token = * index;
6058
6059 type = mailimap_mbx_list_sflag_get_token_value(fd, buffer, &cur_token);
6060 if (type == -1)
6061 return MAILIMAP_ERROR_PARSE;
6062
6063 * result = type;
6064 * index = cur_token;
6065
6066 return MAILIMAP_NO_ERROR;
6067}
6068
6069
6070/*
6071 media-basic = ((DQUOTE ("APPLICATION" / "AUDIO" / "IMAGE" / "MESSAGE" /
6072 "VIDEO") DQUOTE) / string) SP media-subtype
6073 ; Defined in [MIME-IMT]
6074*/
6075
6076/*
6077 DQUOTE ("APPLICATION" / "AUDIO" / "IMAGE" / "MESSAGE" /
6078 "VIDEO") DQUOTE
6079*/
6080
6081static int
6082mailimap_media_basic_standard_parse(mailstream * fd, MMAPString * buffer,
6083 size_t * index,
6084 int * result)
6085{
6086 size_t cur_token;
6087 int type;
6088 int r;
6089
6090 cur_token = * index;
6091
6092 r = mailimap_dquote_parse(fd, buffer, &cur_token);
6093 if (r != MAILIMAP_NO_ERROR)
6094 return r;
6095
6096 type = mailimap_media_basic_get_token_value(fd, buffer, &cur_token);
6097 if (type == -1)
6098 return MAILIMAP_ERROR_PARSE;
6099
6100 r = mailimap_dquote_parse(fd, buffer, &cur_token);
6101 if (r != MAILIMAP_NO_ERROR)
6102 return FALSE;
6103
6104 * index = cur_token;
6105 * result = type;
6106
6107 return MAILIMAP_NO_ERROR;
6108}
6109
6110/*
6111 media-basic = ((DQUOTE ("APPLICATION" / "AUDIO" / "IMAGE" / "MESSAGE" /
6112 "VIDEO") DQUOTE) / string) SP media-subtype
6113 ; Defined in [MIME-IMT]
6114*/
6115
6116static int
6117mailimap_media_basic_parse(mailstream * fd, MMAPString * buffer,
6118 size_t * index,
6119 struct mailimap_media_basic ** result,
6120 size_t progr_rate,
6121 progress_function * progr_fun)
6122{
6123 size_t cur_token;
6124 int type;
6125 char * basic_type;
6126 char * subtype;
6127 struct mailimap_media_basic * media_basic;
6128 int r;
6129 int res;
6130
6131 cur_token = * index;
6132
6133 basic_type = NULL;
6134 subtype = NULL;
6135
6136 r = mailimap_media_basic_standard_parse(fd, buffer, &cur_token,
6137 &type);
6138
6139 if (r == MAILIMAP_ERROR_PARSE) {
6140 r = mailimap_string_parse(fd, buffer, &cur_token, &basic_type, NULL,
6141 progr_rate, progr_fun);
6142 if (r == MAILIMAP_NO_ERROR)
6143 type = MAILIMAP_MEDIA_BASIC_OTHER;
6144 }
6145
6146 if (r != MAILIMAP_NO_ERROR) {
6147 res = r;
6148 goto err;
6149 }
6150
6151 r = mailimap_space_parse(fd, buffer, &cur_token);
6152 if (r != MAILIMAP_NO_ERROR) {
6153 res = r;
6154 goto free_basic_type;
6155 }
6156
6157 r = mailimap_media_subtype_parse(fd, buffer, &cur_token, &subtype,
6158 progr_rate, progr_fun);
6159 if (r != MAILIMAP_NO_ERROR) {
6160 res = r;
6161 goto free_basic_type;
6162 }
6163
6164 media_basic = mailimap_media_basic_new(type, basic_type, subtype);
6165 if (media_basic == NULL) {
6166 res = MAILIMAP_ERROR_MEMORY;
6167 goto free_subtype;
6168 }
6169
6170 * result = media_basic;
6171 * index = cur_token;
6172
6173 return MAILIMAP_NO_ERROR;
6174
6175 free_subtype:
6176 mailimap_media_subtype_free(subtype);
6177 free_basic_type:
6178 if (basic_type != NULL)
6179 mailimap_string_free(basic_type);
6180 err:
6181 return res;
6182}
6183
6184
6185/*
6186 media-message = DQUOTE "MESSAGE" DQUOTE SP DQUOTE "RFC822" DQUOTE
6187 ; Defined in [MIME-IMT]
6188*/
6189
6190static int
6191mailimap_media_message_parse(mailstream * fd, MMAPString * buffer,
6192 size_t * index)
6193{
6194 size_t cur_token;
6195 int r;
6196
6197 cur_token = * index;
6198
6199 r = mailimap_dquote_parse(fd, buffer, &cur_token);
6200 if (r != MAILIMAP_NO_ERROR)
6201 return r;
6202
6203 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6204 "MESSAGE");
6205 if (r != MAILIMAP_NO_ERROR)
6206 return r;
6207
6208 r = mailimap_dquote_parse(fd, buffer, &cur_token);
6209 if (r != MAILIMAP_NO_ERROR)
6210 return r;
6211
6212 r = mailimap_space_parse(fd, buffer, &cur_token);
6213 if (r != MAILIMAP_NO_ERROR)
6214 return r;
6215
6216 r = mailimap_dquote_parse(fd, buffer, &cur_token);
6217 if (r != MAILIMAP_NO_ERROR)
6218 return r;
6219
6220 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6221 "RFC822");
6222 if (r != MAILIMAP_NO_ERROR)
6223 return r;
6224
6225 r = mailimap_dquote_parse(fd, buffer, &cur_token);
6226 if (r != MAILIMAP_NO_ERROR)
6227 return r;
6228
6229 * index = cur_token;
6230
6231 return MAILIMAP_NO_ERROR;
6232}
6233
6234/*
6235 media-subtype = string
6236 ; Defined in [MIME-IMT]
6237*/
6238
6239static int
6240mailimap_media_subtype_parse(mailstream * fd, MMAPString * buffer,
6241 size_t * index,
6242 char ** result,
6243 size_t progr_rate,
6244 progress_function * progr_fun)
6245{
6246 return mailimap_string_parse(fd, buffer, index, result, NULL,
6247 progr_rate, progr_fun);
6248}
6249
6250/*
6251 media-text = DQUOTE "TEXT" DQUOTE SP media-subtype
6252 ; Defined in [MIME-IMT]
6253*/
6254
6255static int mailimap_media_text_parse(mailstream * fd, MMAPString * buffer,
6256 size_t * index,
6257 char ** result,
6258 size_t progr_rate,
6259 progress_function * progr_fun)
6260{
6261 size_t cur_token;
6262 char * media_subtype;
6263 int r;
6264
6265 cur_token = * index;
6266
6267 r = mailimap_dquote_parse(fd, buffer, &cur_token);
6268 if (r != MAILIMAP_NO_ERROR)
6269 return r;
6270
6271 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6272 "TEXT");
6273 if (r != MAILIMAP_NO_ERROR)
6274 return r;
6275
6276 r = mailimap_dquote_parse(fd, buffer, &cur_token);
6277 if (r != MAILIMAP_NO_ERROR)
6278 return r;
6279
6280 r = mailimap_space_parse(fd, buffer, &cur_token);
6281 if (r != MAILIMAP_NO_ERROR)
6282 return r;
6283
6284 r = mailimap_media_subtype_parse(fd, buffer, &cur_token, &media_subtype,
6285 progr_rate, progr_fun);
6286 if (r != MAILIMAP_NO_ERROR)
6287 return r;
6288
6289 * result = media_subtype;
6290 * index = cur_token;
6291
6292 return MAILIMAP_NO_ERROR;
6293}
6294
6295
6296/*
6297 message-data = nz-number SP ("EXPUNGE" / ("FETCH" SP msg-att))
6298*/
6299
6300
6301static int
6302mailimap_message_data_parse(mailstream * fd, MMAPString * buffer,
6303 size_t * index,
6304 struct mailimap_message_data ** result,
6305 size_t progr_rate,
6306 progress_function * progr_fun)
6307{
6308 size_t cur_token;
6309 uint32_t number;
6310 int type;
6311 struct mailimap_msg_att * msg_att;
6312 struct mailimap_message_data * msg_data;
6313 int r;
6314 int res;
6315
6316 cur_token = * index;
6317 msg_att = NULL;
6318
6319 r = mailimap_nz_number_parse(fd, buffer, &cur_token, &number);
6320 if (r != MAILIMAP_NO_ERROR) {
6321 res = r;
6322 goto err;
6323 }
6324
6325 r = mailimap_space_parse(fd, buffer, &cur_token);
6326 if (r != MAILIMAP_NO_ERROR) {
6327 res = r;
6328 goto err;
6329 }
6330
6331 type = MAILIMAP_MESSAGE_DATA_ERROR; /* XXX - removes a gcc warning */
6332
6333 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6334 "EXPUNGE");
6335 if (r == MAILIMAP_NO_ERROR)
6336 type = MAILIMAP_MESSAGE_DATA_EXPUNGE;
6337
6338 if (r == MAILIMAP_ERROR_PARSE) {
6339 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6340 "FETCH");
6341 if (r != MAILIMAP_NO_ERROR) {
6342 res = r;
6343 goto err;
6344 }
6345
6346 r = mailimap_space_parse(fd, buffer, &cur_token);
6347 if (r != MAILIMAP_NO_ERROR) {
6348 res = r;
6349 goto err;
6350 }
6351
6352 r = mailimap_msg_att_parse(fd, buffer, &cur_token, &msg_att,
6353 progr_rate, progr_fun);
6354 if (r != MAILIMAP_NO_ERROR) {
6355 res = r;
6356 goto err;
6357 }
6358
6359 type = MAILIMAP_MESSAGE_DATA_FETCH;
6360 }
6361
6362 if (r != MAILIMAP_NO_ERROR) {
6363 res = r;
6364 goto err;
6365 }
6366
6367 msg_data = mailimap_message_data_new(number, type, msg_att);
6368 if (msg_data == NULL) {
6369 res = MAILIMAP_ERROR_MEMORY;
6370 goto free_msg_att;
6371 }
6372
6373 * result = msg_data;
6374 * index = cur_token;
6375
6376 return MAILIMAP_NO_ERROR;
6377
6378 free_msg_att:
6379 if (msg_att != NULL)
6380 mailimap_msg_att_free(msg_att);
6381 err:
6382 return res;
6383}
6384
6385/*
6386 msg-att = "(" (msg-att-dynamic / msg-att-static)
6387 *(SP (msg-att-dynamic / msg-att-static)) ")"
6388*/
6389
6390/*
6391 msg-att-dynamic / msg-att-static
6392*/
6393
6394static int
6395mailimap_msg_att_item_parse(mailstream * fd, MMAPString * buffer,
6396 size_t * index,
6397 struct mailimap_msg_att_item ** result,
6398 size_t progr_rate,
6399 progress_function * progr_fun)
6400{
6401 int type;
6402 struct mailimap_msg_att_dynamic * msg_att_dynamic;
6403 struct mailimap_msg_att_static * msg_att_static;
6404 size_t cur_token;
6405 struct mailimap_msg_att_item * item;
6406 int r;
6407 int res;
6408
6409 cur_token = * index;
6410
6411 msg_att_dynamic = NULL;
6412 msg_att_static = NULL;
6413
6414 type = MAILIMAP_MSG_ATT_ITEM_ERROR; /* XXX - removes a gcc warning */
6415
6416 r = mailimap_msg_att_dynamic_parse(fd, buffer, &cur_token,
6417 &msg_att_dynamic,
6418 progr_rate, progr_fun);
6419 if (r == MAILIMAP_NO_ERROR)
6420 type = MAILIMAP_MSG_ATT_ITEM_DYNAMIC;
6421
6422 if (r == MAILIMAP_ERROR_PARSE) {
6423 r = mailimap_msg_att_static_parse(fd, buffer, &cur_token,
6424 &msg_att_static,
6425 progr_rate, progr_fun);
6426 if (r == MAILIMAP_NO_ERROR)
6427 type = MAILIMAP_MSG_ATT_ITEM_STATIC;
6428 }
6429
6430 if (r != MAILIMAP_NO_ERROR) {
6431 res = r;
6432 goto err;
6433 }
6434
6435 item = mailimap_msg_att_item_new(type, msg_att_dynamic, msg_att_static);
6436 if (item == NULL) {
6437 res = MAILIMAP_ERROR_MEMORY;
6438 goto free;
6439 }
6440
6441 * result = item;
6442 * index = cur_token;
6443
6444 return MAILIMAP_NO_ERROR;
6445
6446 free:
6447 if (msg_att_dynamic != NULL)
6448 mailimap_msg_att_dynamic_free(msg_att_dynamic);
6449 if (msg_att_static != NULL)
6450 mailimap_msg_att_static_free(msg_att_static);
6451 err:
6452 return res;
6453}
6454
6455/*
6456 msg-att = "(" (msg-att-dynamic / msg-att-static)
6457 *(SP (msg-att-dynamic / msg-att-static)) ")"
6458*/
6459
6460static int
6461mailimap_msg_att_parse(mailstream * fd, MMAPString * buffer,
6462 size_t * index, struct mailimap_msg_att ** result,
6463 size_t progr_rate,
6464 progress_function * progr_fun)
6465{
6466 size_t cur_token;
6467 clist * list;
6468 struct mailimap_msg_att * msg_att;
6469 int r;
6470 int res;
6471
6472 cur_token = * index;
6473 list = NULL;
6474
6475 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
6476 if (r != MAILIMAP_NO_ERROR) {
6477 res = r;
6478 goto err;
6479 }
6480
6481 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, &list,
6482 (mailimap_struct_parser *)
6483 mailimap_msg_att_item_parse,
6484 (mailimap_struct_destructor *)
6485 mailimap_msg_att_item_free,
6486 progr_rate, progr_fun);
6487 if (r != MAILIMAP_NO_ERROR) {
6488 res = r;
6489 goto err;
6490 }
6491
6492 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
6493 if (r != MAILIMAP_NO_ERROR) {
6494 res = r;
6495 goto free;
6496 }
6497
6498 msg_att = mailimap_msg_att_new(list);
6499 if (msg_att == NULL) {
6500 res = MAILIMAP_ERROR_MEMORY;
6501 goto free;
6502 }
6503
6504 * index = cur_token;
6505 * result = msg_att;
6506
6507 return MAILIMAP_NO_ERROR;
6508
6509 free:
6510 clist_foreach(list, (clist_func) mailimap_msg_att_item_free, NULL);
6511 clist_free(list);
6512 err:
6513 return res;
6514}
6515
6516/*
6517 msg-att-dynamic = "FLAGS" SP "(" [flag-fetch *(SP flag-fetch)] ")"
6518 ; MAY change for a message
6519*/
6520
6521
6522static int
6523mailimap_msg_att_dynamic_parse(mailstream * fd, MMAPString * buffer,
6524 size_t * index,
6525 struct mailimap_msg_att_dynamic ** result,
6526 size_t progr_rate,
6527 progress_function * progr_fun)
6528{
6529 clist * list;
6530 struct mailimap_msg_att_dynamic * msg_att_dyn;
6531 size_t cur_token;
6532 int r;
6533 int res;
6534
6535 cur_token = * index;
6536
6537 list = NULL;
6538
6539 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "FLAGS");
6540 if (r != MAILIMAP_NO_ERROR) {
6541 res = r;
6542 goto err;
6543 }
6544
6545 r = mailimap_space_parse(fd, buffer, &cur_token);
6546 if (r != MAILIMAP_NO_ERROR) {
6547 res = r;
6548 goto err;
6549 }
6550
6551 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
6552 if (r != MAILIMAP_NO_ERROR) {
6553 res = r;
6554 goto err;
6555 }
6556
6557 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token,
6558 &list,
6559 (mailimap_struct_parser *)
6560 mailimap_flag_fetch_parse,
6561 (mailimap_struct_destructor *)
6562 mailimap_flag_fetch_free,
6563 progr_rate, progr_fun);
6564 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
6565 res = r;
6566 goto err;
6567 }
6568
6569 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
6570 if (r != MAILIMAP_NO_ERROR) {
6571 res = r;
6572 goto free;
6573 }
6574
6575 msg_att_dyn = mailimap_msg_att_dynamic_new(list);
6576 if (msg_att_dyn == NULL) {
6577 res = MAILIMAP_ERROR_MEMORY;
6578 goto free;
6579 }
6580
6581 * result = msg_att_dyn;
6582 * index = cur_token;
6583
6584 return MAILIMAP_NO_ERROR;
6585
6586 free:
6587 if (list != NULL) {
6588 clist_foreach(list, (clist_func) mailimap_flag_fetch_free, NULL);
6589 clist_free(list);
6590 }
6591 err:
6592 return res;
6593}
6594
6595/*
6596 msg-att-static = "ENVELOPE" SP envelope / "INTERNALDATE" SP date-time /
6597 "RFC822" [".HEADER" / ".TEXT"] SP nstring /
6598 "RFC822.SIZE" SP number / "BODY" ["STRUCTURE"] SP body /
6599 "BODY" section ["<" number ">"] SP nstring /
6600 "UID" SP uniqueid
6601 ; MUST NOT change for a message
6602*/
6603
6604/*
6605 "ENVELOPE" SP envelope
6606*/
6607
6608
6609static int
6610mailimap_msg_att_envelope_parse(mailstream * fd,
6611 MMAPString * buffer,
6612 size_t * index,
6613 struct mailimap_envelope ** result,
6614 size_t progr_rate,
6615 progress_function * progr_fun)
6616{
6617 size_t cur_token;
6618 struct mailimap_envelope * env;
6619 int r;
6620
6621 cur_token = * index;
6622
6623 r = mailimap_token_case_insensitive_parse(fd, buffer,
6624 &cur_token, "ENVELOPE");
6625 if (r != MAILIMAP_NO_ERROR)
6626 return r;
6627
6628 r = mailimap_space_parse(fd, buffer, &cur_token);
6629 if (r != MAILIMAP_NO_ERROR)
6630 return r;
6631
6632 r = mailimap_envelope_parse(fd, buffer, &cur_token, &env,
6633 progr_rate, progr_fun);
6634 if (r != MAILIMAP_NO_ERROR)
6635 return r;
6636
6637 * index = cur_token;
6638 * result = env;
6639
6640 return MAILIMAP_NO_ERROR;
6641}
6642
6643
6644/*
6645 "INTERNALDATE" SP date-time
6646*/
6647
6648
6649static int
6650mailimap_msg_att_internaldate_parse(mailstream * fd, MMAPString * buffer,
6651 size_t * index,
6652 struct mailimap_date_time ** result,
6653 size_t progr_rate,
6654 progress_function * progr_fun)
6655{
6656 size_t cur_token;
6657 struct mailimap_date_time * date_time;
6658 int r;
6659
6660 cur_token = * index;
6661
6662 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6663 "INTERNALDATE");
6664 if (r != MAILIMAP_NO_ERROR)
6665 return r;
6666
6667 r = mailimap_space_parse(fd, buffer, &cur_token);
6668 if (r != MAILIMAP_NO_ERROR)
6669 return FALSE;
6670
6671 r = mailimap_date_time_parse(fd, buffer, &cur_token, &date_time,
6672 progr_rate, progr_fun);
6673 if (r != MAILIMAP_NO_ERROR)
6674 return r;
6675
6676 * result = date_time;
6677 * index = cur_token;
6678
6679 return MAILIMAP_NO_ERROR;
6680}
6681
6682/*
6683 "RFC822" SP nstring
6684*/
6685
6686static int
6687mailimap_msg_att_rfc822_parse(mailstream * fd, MMAPString * buffer,
6688 size_t * index, char ** result,
6689 size_t * result_len,
6690 size_t progr_rate,
6691 progress_function * progr_fun)
6692{
6693 size_t cur_token;
6694 char * rfc822_message;
6695 int r;
6696 size_t length;
6697
6698 cur_token = * index;
6699
6700 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6701 "RFC822");
6702 if (r != MAILIMAP_NO_ERROR)
6703 return r;
6704
6705 r = mailimap_space_parse(fd, buffer, &cur_token);
6706 if (r != MAILIMAP_NO_ERROR)
6707 return r;
6708
6709 r = mailimap_nstring_parse(fd, buffer, &cur_token, &rfc822_message, &length,
6710 progr_rate, progr_fun);
6711 if (r != MAILIMAP_NO_ERROR)
6712 return r;
6713
6714 * result = rfc822_message;
6715 if (result_len != NULL)
6716 * result_len = length;
6717 * index = cur_token;
6718
6719 return MAILIMAP_NO_ERROR;
6720}
6721
6722/*
6723 "RFC822" ".HEADER" SP nstring
6724*/
6725
6726static int
6727mailimap_msg_att_rfc822_header_parse(mailstream * fd, MMAPString * buffer,
6728 size_t * index, char ** result,
6729 size_t * result_len,
6730 size_t progr_rate,
6731 progress_function * progr_fun)
6732{
6733 size_t cur_token;
6734 char * rfc822_header;
6735 int r;
6736 size_t length;
6737
6738 cur_token = * index;
6739
6740 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6741 "RFC822");
6742 if (r != MAILIMAP_NO_ERROR)
6743 return r;
6744
6745 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6746 ".HEADER");
6747 if (r != MAILIMAP_NO_ERROR)
6748 return r;
6749
6750 r = mailimap_space_parse(fd, buffer, &cur_token);
6751 if (r != MAILIMAP_NO_ERROR)
6752 return r;
6753
6754 r = mailimap_nstring_parse(fd, buffer, &cur_token, &rfc822_header, &length,
6755 progr_rate, progr_fun);
6756 if (r != MAILIMAP_NO_ERROR)
6757 return r;
6758
6759 * result = rfc822_header;
6760 if (result_len != NULL)
6761 * result_len = length;
6762 * index = cur_token;
6763
6764 return MAILIMAP_NO_ERROR;
6765}
6766
6767/*
6768 "RFC822" ".TEXT" SP nstring
6769*/
6770
6771static int
6772mailimap_msg_att_rfc822_text_parse(mailstream * fd, MMAPString * buffer,
6773 size_t * index, char ** result,
6774 size_t * result_len,
6775 size_t progr_rate,
6776 progress_function * progr_fun)
6777{
6778 size_t cur_token;
6779 char * rfc822_text;
6780 int r;
6781 size_t length;
6782
6783 cur_token = * index;
6784
6785 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6786 "RFC822");
6787 if (r != MAILIMAP_NO_ERROR)
6788 return r;
6789
6790 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6791 ".TEXT");
6792 if (r != MAILIMAP_NO_ERROR)
6793 return r;
6794
6795 r = mailimap_space_parse(fd, buffer, &cur_token);
6796 if (r != MAILIMAP_NO_ERROR)
6797 return r;
6798
6799 r = mailimap_nstring_parse(fd, buffer, &cur_token, &rfc822_text, &length,
6800 progr_rate, progr_fun);
6801 if (r != MAILIMAP_NO_ERROR)
6802 return r;
6803
6804 * result = rfc822_text;
6805 if (result_len != NULL)
6806 * result_len = length;
6807 * index = cur_token;
6808
6809 return MAILIMAP_NO_ERROR;
6810}
6811
6812/*
6813 "RFC822.SIZE" SP number
6814*/
6815
6816static int
6817mailimap_msg_att_rfc822_size_parse(mailstream * fd, MMAPString * buffer,
6818 size_t * index, uint32_t * result)
6819{
6820 size_t cur_token;
6821 uint32_t number;
6822 int r;
6823
6824 cur_token = * index;
6825
6826 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6827 "RFC822.SIZE");
6828 if (r != MAILIMAP_NO_ERROR)
6829 return r;
6830
6831 r = mailimap_space_parse(fd, buffer, &cur_token);
6832 if (r != MAILIMAP_NO_ERROR)
6833 return r;
6834
6835 r = mailimap_number_parse(fd, buffer, &cur_token, &number);
6836 if (r != MAILIMAP_NO_ERROR)
6837 return r;
6838
6839 * result = number;
6840 * index = cur_token;
6841
6842 return MAILIMAP_NO_ERROR;
6843}
6844
6845/*
6846 "BODY" SP body
6847*/
6848
6849
6850static int
6851mailimap_msg_att_body_parse(mailstream * fd, MMAPString * buffer,
6852 size_t * index, struct mailimap_body ** result,
6853 size_t progr_rate,
6854 progress_function * progr_fun)
6855{
6856 struct mailimap_body * body;
6857 size_t cur_token;
6858 int r;
6859
6860 cur_token = * index;
6861
6862 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6863 "BODY");
6864 if (r != MAILIMAP_NO_ERROR)
6865 return r;
6866
6867 r = mailimap_space_parse(fd, buffer, &cur_token);
6868 if (r != MAILIMAP_NO_ERROR)
6869 return r;
6870
6871 r = mailimap_body_parse(fd, buffer, &cur_token, &body,
6872 progr_rate, progr_fun);
6873 if (r != MAILIMAP_NO_ERROR)
6874 return r;
6875
6876 * result = body;
6877 * index = cur_token;
6878
6879 return MAILIMAP_NO_ERROR;
6880}
6881
6882/*
6883 "BODY" "STRUCTURE" SP body
6884*/
6885
6886
6887static int
6888mailimap_msg_att_bodystructure_parse(mailstream * fd, MMAPString * buffer,
6889 size_t * index,
6890 struct mailimap_body ** result,
6891 size_t progr_rate,
6892 progress_function * progr_fun)
6893{
6894 struct mailimap_body * body;
6895 size_t cur_token;
6896 int r;
6897
6898 cur_token = * index;
6899
6900 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6901 "BODY");
6902 if (r != MAILIMAP_NO_ERROR)
6903 return r;
6904
6905 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6906 "STRUCTURE");
6907 if (r != MAILIMAP_NO_ERROR)
6908 return r;
6909
6910 r = mailimap_space_parse(fd, buffer, &cur_token);
6911 if (r != MAILIMAP_NO_ERROR)
6912 return r;
6913
6914 r = mailimap_body_parse(fd, buffer, &cur_token, &body,
6915 progr_rate, progr_fun);
6916 if (r != MAILIMAP_NO_ERROR)
6917 return r;
6918
6919 * result = body;
6920 * index = cur_token;
6921
6922 return MAILIMAP_NO_ERROR;
6923}
6924
6925/*
6926 "BODY" section ["<" number ">"] SP nstring
6927*/
6928
6929static int
6930mailimap_msg_att_body_section_parse(mailstream * fd, MMAPString * buffer,
6931 size_t * index,
6932 struct mailimap_msg_att_body_section **
6933 result,
6934 size_t progr_rate,
6935 progress_function * progr_fun)
6936{
6937 size_t cur_token;
6938 uint32_t number;
6939 struct mailimap_section * section;
6940 char * body_part;
6941 struct mailimap_msg_att_body_section * msg_att_body_section;
6942 int r;
6943 int res;
6944 size_t length;
6945
6946 cur_token = * index;
6947
6948 section = NULL;
6949 number = 0;
6950 body_part = NULL;
6951
6952 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
6953 "BODY");
6954 if (r != MAILIMAP_NO_ERROR) {
6955 res = r;
6956 goto err;
6957 }
6958
6959 r = mailimap_section_parse(fd, buffer, &cur_token, &section,
6960 progr_rate, progr_fun);
6961 if (r != MAILIMAP_NO_ERROR) {
6962 res = r;
6963 goto err;
6964 }
6965
6966 r = mailimap_lower_parse(fd, buffer, &cur_token);
6967 switch (r) {
6968 case MAILIMAP_NO_ERROR:
6969 r = mailimap_number_parse(fd, buffer, &cur_token, &number);
6970 if (r != MAILIMAP_NO_ERROR) {
6971 res = r;
6972 goto free_section;
6973 }
6974
6975 r = mailimap_greater_parse(fd, buffer, &cur_token);
6976 if (r != MAILIMAP_NO_ERROR) {
6977 res = r;
6978 goto free_section;
6979 }
6980 break;
6981
6982 case MAILIMAP_ERROR_PARSE:
6983 break;
6984
6985 default:
6986 return r;
6987 }
6988
6989 r = mailimap_space_parse(fd, buffer, &cur_token);
6990 if (r != MAILIMAP_NO_ERROR) {
6991 res = r;
6992 goto free_section;
6993 }
6994
6995 r = mailimap_nstring_parse(fd, buffer, &cur_token, &body_part, &length,
6996 progr_rate, progr_fun);
6997 if (r != MAILIMAP_NO_ERROR) {
6998 res = r;
6999 goto free_section;
7000 }
7001
7002 msg_att_body_section =
7003 mailimap_msg_att_body_section_new(section, number, body_part, length);
7004 if (msg_att_body_section == NULL) {
7005 res = MAILIMAP_ERROR_MEMORY;
7006 goto free_string;
7007 }
7008
7009 * result = msg_att_body_section;
7010 * index = cur_token;
7011
7012 return MAILIMAP_NO_ERROR;
7013
7014 free_string:
7015 mailimap_nstring_free(body_part);
7016 free_section:
7017 if (section != NULL)
7018 mailimap_section_free(section);
7019 err:
7020 return res;
7021}
7022
7023/*
7024 "UID" SP uniqueid
7025*/
7026
7027static int
7028mailimap_msg_att_uid_parse(mailstream * fd, MMAPString * buffer,
7029 size_t * index,
7030 uint32_t * result)
7031{
7032 size_t cur_token;
7033 uint32_t uid;
7034 int r;
7035
7036 cur_token = * index;
7037
7038 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "UID");
7039 if (r != MAILIMAP_NO_ERROR)
7040 return r;
7041
7042 r = mailimap_space_parse(fd, buffer, &cur_token);
7043 if (r != MAILIMAP_NO_ERROR)
7044 return r;
7045
7046 r = mailimap_uniqueid_parse(fd, buffer, &cur_token, &uid);
7047 if (r != MAILIMAP_NO_ERROR)
7048 return r;
7049
7050 * index = cur_token;
7051 * result = uid;
7052
7053 return MAILIMAP_NO_ERROR;
7054}
7055
7056/*
7057 msg-att-static = "ENVELOPE" SP envelope / "INTERNALDATE" SP date-time /
7058 "RFC822" [".HEADER" / ".TEXT"] SP nstring /
7059 "RFC822.SIZE" SP number / "BODY" ["STRUCTURE"] SP body /
7060 "BODY" section ["<" number ">"] SP nstring /
7061 "UID" SP uniqueid
7062 ; MUST NOT change for a message
7063*/
7064
7065static int
7066mailimap_msg_att_static_parse(mailstream * fd, MMAPString * buffer,
7067 size_t * index,
7068 struct mailimap_msg_att_static ** result,
7069 size_t progr_rate,
7070 progress_function * progr_fun)
7071{
7072 size_t cur_token;
7073 struct mailimap_envelope * env;
7074 struct mailimap_date_time * internal_date;
7075 char * rfc822;
7076 char * rfc822_header;
7077 char * rfc822_text;
7078 uint32_t rfc822_size;
7079 struct mailimap_body * bodystructure;
7080 struct mailimap_body * body;
7081 struct mailimap_msg_att_body_section * body_section;
7082 uint32_t uid;
7083 struct mailimap_msg_att_static * msg_att_static;
7084 int type;
7085 int r;
7086 int res;
7087 size_t length;
7088
7089 cur_token = * index;
7090
7091 env = NULL;
7092 internal_date = NULL;
7093 rfc822 = NULL;
7094 rfc822_header = NULL;
7095 rfc822_text = NULL;
7096 rfc822_size = 0;
7097 length = 0;
7098 bodystructure = NULL;
7099 body = NULL;
7100 body_section = NULL;
7101 uid = 0;
7102
7103 type = MAILIMAP_MSG_ATT_ERROR; /* XXX - removes a gcc warning */
7104
7105 r = mailimap_msg_att_envelope_parse(fd, buffer, &cur_token, &env,
7106 progr_rate, progr_fun);
7107 if (r == MAILIMAP_NO_ERROR)
7108 type = MAILIMAP_MSG_ATT_ENVELOPE;
7109
7110 if (r == MAILIMAP_ERROR_PARSE) {
7111 r = mailimap_msg_att_internaldate_parse(fd, buffer, &cur_token,
7112 &internal_date,
7113 progr_rate, progr_fun);
7114 if (r == MAILIMAP_NO_ERROR)
7115 type = MAILIMAP_MSG_ATT_INTERNALDATE;
7116 }
7117
7118 if (r == MAILIMAP_ERROR_PARSE) {
7119 r = mailimap_msg_att_rfc822_parse(fd, buffer, &cur_token,
7120 &rfc822, &length,
7121 progr_rate, progr_fun);
7122 if (r == MAILIMAP_NO_ERROR)
7123 type = MAILIMAP_MSG_ATT_RFC822;
7124 }
7125
7126 if (r == MAILIMAP_ERROR_PARSE) {
7127 r = mailimap_msg_att_rfc822_header_parse(fd, buffer, &cur_token,
7128 &rfc822_header, &length,
7129 progr_rate, progr_fun);
7130 type = MAILIMAP_MSG_ATT_RFC822_HEADER;
7131 }
7132
7133 if (r == MAILIMAP_ERROR_PARSE) {
7134 r = mailimap_msg_att_rfc822_text_parse(fd, buffer, &cur_token,
7135 &rfc822_text, &length,
7136 progr_rate, progr_fun);
7137 if (r == MAILIMAP_NO_ERROR)
7138 type = MAILIMAP_MSG_ATT_RFC822_TEXT;
7139 }
7140
7141 if (r == MAILIMAP_ERROR_PARSE) {
7142 r = mailimap_msg_att_rfc822_size_parse(fd, buffer, &cur_token,
7143 &rfc822_size);
7144 if (r == MAILIMAP_NO_ERROR)
7145 type = MAILIMAP_MSG_ATT_RFC822_SIZE;
7146 }
7147
7148 if (r == MAILIMAP_ERROR_PARSE) {
7149 r = mailimap_msg_att_body_parse(fd, buffer, &cur_token,
7150 &body, progr_rate, progr_fun);
7151 if (r == MAILIMAP_NO_ERROR)
7152 type = MAILIMAP_MSG_ATT_BODY;
7153 }
7154
7155 if (r == MAILIMAP_ERROR_PARSE) {
7156 r = mailimap_msg_att_bodystructure_parse(fd, buffer, &cur_token,
7157 &bodystructure,
7158 progr_rate, progr_fun);
7159 if (r == MAILIMAP_NO_ERROR)
7160 type = MAILIMAP_MSG_ATT_BODYSTRUCTURE;
7161 }
7162
7163 if (r == MAILIMAP_ERROR_PARSE) {
7164 r = mailimap_msg_att_body_section_parse(fd, buffer, &cur_token,
7165 &body_section,
7166 progr_rate, progr_fun);
7167 if (r == MAILIMAP_NO_ERROR)
7168 type = MAILIMAP_MSG_ATT_BODY_SECTION;
7169 }
7170
7171 if (r == MAILIMAP_ERROR_PARSE) {
7172 r = mailimap_msg_att_uid_parse(fd, buffer, &cur_token,
7173 &uid);
7174 if (r == MAILIMAP_NO_ERROR)
7175 type = MAILIMAP_MSG_ATT_UID;
7176 }
7177
7178 if (r != MAILIMAP_NO_ERROR) {
7179 res = r;
7180 goto err;
7181 }
7182
7183 msg_att_static = mailimap_msg_att_static_new(type, env, internal_date,
7184 rfc822, rfc822_header,
7185 rfc822_text, length,
7186 rfc822_size, bodystructure,
7187 body, body_section, uid);
7188 if (msg_att_static == NULL) {
7189 res = MAILIMAP_ERROR_MEMORY;
7190 goto free;
7191 }
7192
7193 * result = msg_att_static;
7194 * index = cur_token;
7195
7196 return MAILIMAP_NO_ERROR;
7197
7198 free:
7199 if (env)
7200 mailimap_msg_att_envelope_free(env);
7201 if (internal_date)
7202 mailimap_msg_att_internaldate_free(internal_date);
7203 if (rfc822)
7204 mailimap_msg_att_rfc822_free(rfc822);
7205 if (rfc822_header)
7206 mailimap_msg_att_rfc822_header_free(rfc822_header);
7207 if (rfc822_text)
7208 mailimap_msg_att_rfc822_text_free(rfc822_text);
7209 if (bodystructure)
7210 mailimap_msg_att_bodystructure_free(bodystructure);
7211 if (body)
7212 mailimap_msg_att_body_free(body);
7213 if (body_section)
7214 mailimap_msg_att_body_section_free(body_section);
7215 err:
7216 return res;
7217}
7218
7219
7220/*
7221 nil = "NIL"
7222*/
7223
7224static int mailimap_nil_parse(mailstream * fd, MMAPString * buffer,
7225 size_t * index)
7226{
7227 return mailimap_token_case_insensitive_parse(fd, buffer, index, "NIL");
7228}
7229
7230/*
7231 nstring = string / nil
7232*/
7233
7234
7235static int mailimap_nstring_parse(mailstream * fd, MMAPString * buffer,
7236 size_t * index, char ** result,
7237 size_t * result_len,
7238 size_t progr_rate,
7239 progress_function * progr_fun)
7240{
7241 int r;
7242
7243 r = mailimap_string_parse(fd, buffer, index, result, result_len,
7244 progr_rate, progr_fun);
7245 switch (r) {
7246 case MAILIMAP_NO_ERROR:
7247 return MAILIMAP_NO_ERROR;
7248
7249 case MAILIMAP_ERROR_PARSE:
7250 r = mailimap_nil_parse(fd, buffer, index);
7251 if (r != MAILIMAP_NO_ERROR) {
7252 return r;
7253 }
7254
7255 * result = NULL;
7256 if (result_len != NULL)
7257 * result_len = 0;
7258 return MAILIMAP_NO_ERROR;
7259
7260 default:
7261 return r;
7262 }
7263}
7264
7265/*
7266 number = 1*DIGIT
7267 ; Unsigned 32-bit integer
7268 ; (0 <= n < 4,294,967,296)
7269*/
7270
7271static int
7272mailimap_number_parse(mailstream * fd, MMAPString * buffer,
7273 size_t * index, uint32_t * result)
7274{
7275 size_t cur_token;
7276 int digit;
7277 uint32_t number;
7278 int parsed;
7279 int r;
7280
7281 cur_token = * index;
7282 parsed = FALSE;
7283
7284#ifdef UNSTRICT_SYNTAX
7285 mailimap_space_parse(fd, buffer, &cur_token);
7286#endif
7287
7288 number = 0;
7289 while (1) {
7290 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit);
7291 if (r == MAILIMAP_ERROR_PARSE)
7292 break;
7293 else if (r == MAILIMAP_NO_ERROR) {
7294 number *= 10;
7295 number += digit;
7296 parsed = TRUE;
7297 }
7298 else
7299 return r;
7300 }
7301
7302 if (!parsed)
7303 return MAILIMAP_ERROR_PARSE;
7304
7305 * result = number;
7306 * index = cur_token;
7307
7308 return MAILIMAP_NO_ERROR;
7309}
7310
7311/*
7312 nz-number = digit-nz *DIGIT
7313 ; Non-zero unsigned 32-bit integer
7314 ; (0 < n < 4,294,967,296)
7315*/
7316
7317static int
7318mailimap_nz_number_parse(mailstream * fd, MMAPString * buffer,
7319 size_t * index, uint32_t * result)
7320{
7321#ifdef UNSTRICT_SYNTAX
7322 size_t cur_token;
7323 uint32_t number;
7324 int r;
7325
7326 cur_token = * index;
7327
7328 r = mailimap_number_parse(fd, buffer, &cur_token, &number);
7329 if (r != MAILIMAP_NO_ERROR)
7330 return r;
7331
7332 if (number == 0)
7333 return MAILIMAP_ERROR_PARSE;
7334
7335#else
7336 size_t cur_token;
7337 int digit;
7338 uint32_t number;
7339 int r;
7340
7341 cur_token = * index;
7342
7343 r = mailimap_digit_nz_parse(fd, buffer, &cur_token, &digit);
7344 if (r != MAILIMAP_NO_ERROR)
7345 return r;
7346
7347 number = digit;
7348
7349 while (1) {
7350 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit);
7351 if (r == MAILIMAP_ERROR_PARSE)
7352 break;
7353 else if (r == MAILIMAP_NO_ERROR) {
7354 number *= 10;
7355 number += (guint32) digit;
7356 }
7357 else
7358 return r;
7359 }
7360#endif
7361
7362 * result = number;
7363 * index = cur_token;
7364
7365 return MAILIMAP_NO_ERROR;
7366}
7367
7368/*
7369 password = astring
7370*/
7371
7372/*
7373 quoted = DQUOTE *QUOTED-CHAR DQUOTE
7374*/
7375
7376static int
7377mailimap_quoted_parse(mailstream * fd, MMAPString * buffer,
7378 size_t * index, char ** result,
7379 size_t progr_rate,
7380 progress_function * progr_fun)
7381{
7382 char ch;
7383 size_t cur_token;
7384 MMAPString * gstr_quoted;
7385 int r;
7386 int res;
7387
7388 cur_token = * index;
7389
7390#ifdef UNSTRICT_SYNTAX
7391 r = mailimap_space_parse(fd, buffer, &cur_token);
7392 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
7393 return r;
7394#endif
7395
7396 r = mailimap_dquote_parse(fd, buffer, &cur_token);
7397 if (r != MAILIMAP_NO_ERROR) {
7398 res = r;
7399 goto err;
7400 }
7401
7402 gstr_quoted = mmap_string_new("");
7403 if (gstr_quoted == NULL) {
7404 res = MAILIMAP_ERROR_MEMORY;
7405 goto err;
7406 }
7407
7408 while (1) {
7409 r = mailimap_quoted_char_parse(fd, buffer, &cur_token, &ch);
7410 if (r == MAILIMAP_ERROR_PARSE)
7411 break;
7412 else if (r == MAILIMAP_NO_ERROR) {
7413 if (mmap_string_append_c(gstr_quoted, ch) == NULL) {
7414 res = MAILIMAP_ERROR_MEMORY;
7415 goto free;
7416 }
7417 }
7418 else {
7419 res = r;
7420 goto free;
7421 }
7422 }
7423
7424 r = mailimap_dquote_parse(fd, buffer, &cur_token);
7425 if (r != MAILIMAP_NO_ERROR) {
7426 res = r;
7427 goto free;
7428 }
7429
7430 if (mmap_string_ref(gstr_quoted) < 0) {
7431 res = MAILIMAP_ERROR_MEMORY;
7432 goto free;
7433 }
7434
7435 * index = cur_token;
7436 * result = gstr_quoted->str;
7437
7438 return MAILIMAP_NO_ERROR;
7439
7440 free:
7441 mmap_string_free(gstr_quoted);
7442 err:
7443 return res;
7444}
7445
7446/*
7447 QUOTED-CHAR = <any TEXT-CHAR except quoted-specials> /
7448 "\" quoted-specials
7449*/
7450
7451static int is_quoted_specials(char ch);
7452
7453static int
7454mailimap_quoted_char_parse(mailstream * fd, MMAPString * buffer,
7455 size_t * index, char * result)
7456{
7457 size_t cur_token;
7458 int r;
7459
7460 cur_token = * index;
7461
7462 if (!is_quoted_specials(buffer->str[cur_token])) {
7463 * result = buffer->str[cur_token];
7464 cur_token ++;
7465 * index = cur_token;
7466 return MAILIMAP_NO_ERROR;
7467 }
7468 else {
7469 char quoted_special;
7470
7471 r = mailimap_char_parse(fd, buffer, &cur_token, '\\');
7472 if (r != MAILIMAP_NO_ERROR)
7473 return r;
7474
7475 r = mailimap_quoted_specials_parse(fd, buffer, &cur_token,
7476 &quoted_special);
7477 if (r != MAILIMAP_NO_ERROR)
7478 return r;
7479
7480 * result = quoted_special;
7481 * index = cur_token;
7482
7483 return MAILIMAP_NO_ERROR;
7484 }
7485}
7486
7487/*
7488 quoted-specials = DQUOTE / "\"
7489*/
7490
7491static int is_quoted_specials(char ch)
7492{
7493 return (ch == '\"') || (ch == '\\');
7494}
7495
7496static int
7497mailimap_quoted_specials_parse(mailstream * fd, MMAPString * buffer,
7498 size_t * index, char * result)
7499{
7500 size_t cur_token;
7501
7502 cur_token = * index;
7503
7504 if (is_quoted_specials(buffer->str[cur_token])) {
7505 * result = buffer->str[cur_token];
7506 cur_token ++;
7507 * index = cur_token;
7508 return MAILIMAP_NO_ERROR;
7509 }
7510 else
7511 return MAILIMAP_ERROR_PARSE;
7512}
7513
7514/*
7515 UNIMPLEMENTED
7516 rename = "RENAME" SP mailbox SP mailbox
7517 ; Use of INBOX as a destination gives a NO error
7518*/
7519
7520/*
7521 response = *(continue-req / response-data) response-done
7522*/
7523
7524/*
7525 continue-req / response-data
7526*/
7527
7528/* static */ int
7529mailimap_cont_req_or_resp_data_parse(mailstream * fd, MMAPString * buffer,
7530 size_t * index,
7531 struct mailimap_cont_req_or_resp_data **
7532 result,
7533 size_t progr_rate,
7534 progress_function * progr_fun)
7535{
7536 size_t cur_token;
7537 struct mailimap_cont_req_or_resp_data * cont_req_or_resp_data;
7538 struct mailimap_continue_req * cont_req;
7539 struct mailimap_response_data * resp_data;
7540 int type;
7541 int r;
7542 int res;
7543
7544 cur_token = * index;
7545
7546 cont_req = NULL;
7547 resp_data = NULL;
7548 type = MAILIMAP_RESP_ERROR; /* XXX - removes a gcc warning */
7549
7550 r = mailimap_continue_req_parse(fd, buffer, &cur_token, &cont_req,
7551 progr_rate, progr_fun);
7552 if (r == MAILIMAP_NO_ERROR)
7553 type = MAILIMAP_RESP_CONT_REQ;
7554
7555 if (r == MAILIMAP_ERROR_PARSE) {
7556 r = mailimap_response_data_parse(fd, buffer, &cur_token, &resp_data,
7557 progr_rate, progr_fun);
7558 if (r == MAILIMAP_NO_ERROR)
7559 type = MAILIMAP_RESP_RESP_DATA;
7560 }
7561
7562 if (r != MAILIMAP_NO_ERROR) {
7563 res = r;
7564 goto err;
7565 }
7566
7567 /*
7568 multi-lines response
7569 read another response line because after that token,
7570 there must have something (continue-req, response-data or response-done)
7571 */
7572
7573 if (!mailstream_read_line_append(fd, buffer)) {
7574 res = MAILIMAP_ERROR_STREAM;
7575 goto free;
7576 }
7577
7578 cont_req_or_resp_data =
7579 mailimap_cont_req_or_resp_data_new(type, cont_req, resp_data);
7580 if (cont_req_or_resp_data == NULL) {
7581 res = MAILIMAP_ERROR_MEMORY;
7582 goto free;
7583 }
7584
7585 * result = cont_req_or_resp_data;
7586 * index = cur_token;
7587
7588 return MAILIMAP_NO_ERROR;
7589
7590 free:
7591 if (cont_req != NULL)
7592 mailimap_continue_req_free(cont_req);
7593 if (resp_data != NULL)
7594 mailimap_response_data_free(resp_data);
7595 err:
7596 return res;
7597}
7598
7599/*
7600 response = *(continue-req / response-data) response-done
7601*/
7602
7603int
7604mailimap_response_parse(mailstream * fd, MMAPString * buffer,
7605 size_t * index, struct mailimap_response ** result,
7606 size_t progr_rate,
7607 progress_function * progr_fun)
7608{
7609 size_t cur_token;
7610 clist * cont_req_or_resp_data_list;
7611 struct mailimap_response * resp;
7612 struct mailimap_response_done * resp_done;
7613 int r;
7614 int res;
7615
7616 cur_token = * index;
7617 cont_req_or_resp_data_list = NULL;
7618 resp_done = NULL;
7619
7620 r = mailimap_struct_multiple_parse(fd, buffer,
7621 &cur_token, &cont_req_or_resp_data_list,
7622 (mailimap_struct_parser *)
7623 mailimap_cont_req_or_resp_data_parse,
7624 (mailimap_struct_destructor *)
7625 mailimap_cont_req_or_resp_data_free,
7626 progr_rate, progr_fun);
7627
7628 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
7629 return r;
7630
7631 r = mailimap_response_done_parse(fd, buffer, &cur_token, &resp_done,
7632 progr_rate, progr_fun);
7633 if (r != MAILIMAP_NO_ERROR) {
7634 res = r;
7635 goto free_list;
7636 }
7637
7638 resp = mailimap_response_new(cont_req_or_resp_data_list, resp_done);
7639 if (resp == NULL) {
7640 res = MAILIMAP_ERROR_MEMORY;
7641 goto free_resp_done;
7642 }
7643
7644 * result = resp;
7645 * index = cur_token;
7646
7647 return MAILIMAP_NO_ERROR;
7648
7649 free_resp_done:
7650 mailimap_response_done_free(resp_done);
7651 free_list:
7652 if (cont_req_or_resp_data_list != NULL) {
7653 clist_foreach(cont_req_or_resp_data_list,
7654 (clist_func) mailimap_cont_req_or_resp_data_free, NULL);
7655 clist_free(cont_req_or_resp_data_list);
7656 }
7657 return res;
7658}
7659
7660/*
7661 response-data = "*" SP (resp-cond-state / resp-cond-bye /
7662 mailbox-data / message-data / capability-data) CRLF
7663*/
7664
7665static int
7666mailimap_response_data_parse(mailstream * fd, MMAPString * buffer,
7667 size_t * index,
7668 struct mailimap_response_data ** result,
7669 size_t progr_rate,
7670 progress_function * progr_fun)
7671{
7672 struct mailimap_response_data * resp_data;
7673 size_t cur_token;
7674 int type;
7675 struct mailimap_resp_cond_state * cond_state;
7676 struct mailimap_resp_cond_bye * cond_bye;
7677 struct mailimap_mailbox_data * mb_data;
7678 struct mailimap_message_data * msg_data;
7679 struct mailimap_capability_data * cap_data;
7680 int r;
7681 int res;
7682
7683 cond_state = NULL;
7684 cond_bye = NULL;
7685 mb_data = NULL;
7686 msg_data = NULL;
7687 cap_data = NULL;
7688
7689 cur_token = * index;
7690
7691 r = mailimap_star_parse(fd, buffer, &cur_token);
7692 if (r != MAILIMAP_NO_ERROR) {
7693 res = r;
7694 goto err;
7695 }
7696
7697 r = mailimap_space_parse(fd, buffer, &cur_token);
7698 if (r != MAILIMAP_NO_ERROR) {
7699 res = r;
7700 goto err;
7701 }
7702
7703 type = MAILIMAP_RESP_DATA_TYPE_ERROR; /* XXX - removes a gcc warning */
7704
7705 r = mailimap_resp_cond_state_parse(fd, buffer, &cur_token, &cond_state,
7706 progr_rate, progr_fun);
7707 if (r == MAILIMAP_NO_ERROR)
7708 type = MAILIMAP_RESP_DATA_TYPE_COND_STATE;
7709
7710 if (r == MAILIMAP_ERROR_PARSE) {
7711 r = mailimap_resp_cond_bye_parse(fd, buffer, &cur_token, &cond_bye,
7712 progr_rate, progr_fun);
7713 if (r == MAILIMAP_NO_ERROR)
7714 type = MAILIMAP_RESP_DATA_TYPE_COND_BYE;
7715 }
7716
7717 if (r == MAILIMAP_ERROR_PARSE) {
7718 r = mailimap_mailbox_data_parse(fd, buffer, &cur_token, &mb_data,
7719 progr_rate, progr_fun);
7720 if (r == MAILIMAP_NO_ERROR)
7721 type = MAILIMAP_RESP_DATA_TYPE_MAILBOX_DATA;
7722 }
7723
7724 if (r == MAILIMAP_ERROR_PARSE) {
7725 r = mailimap_message_data_parse(fd, buffer, &cur_token, &msg_data,
7726 progr_rate, progr_fun);
7727 if (r == MAILIMAP_NO_ERROR)
7728 type = MAILIMAP_RESP_DATA_TYPE_MESSAGE_DATA;
7729 }
7730
7731 if (r == MAILIMAP_ERROR_PARSE) {
7732 r = mailimap_capability_data_parse(fd, buffer, &cur_token, &cap_data,
7733 progr_rate, progr_fun);
7734 if (r == MAILIMAP_NO_ERROR)
7735 type = MAILIMAP_RESP_DATA_TYPE_CAPABILITY_DATA;
7736 }
7737
7738 if (r != MAILIMAP_NO_ERROR) {
7739 res = r;
7740 goto err;
7741 }
7742
7743 r = mailimap_crlf_parse(fd, buffer, &cur_token);
7744 if (r != MAILIMAP_NO_ERROR) {
7745 res = r;
7746 goto free;
7747 }
7748
7749 resp_data = mailimap_response_data_new(type, cond_state,
7750 cond_bye, mb_data,
7751 msg_data, cap_data);
7752 if (resp_data == NULL) {
7753 res = MAILIMAP_ERROR_MEMORY;
7754 goto free;
7755 }
7756
7757 * result = resp_data;
7758 * index = cur_token;
7759
7760 return MAILIMAP_NO_ERROR;
7761
7762 free:
7763 if (cond_state)
7764 mailimap_resp_cond_state_free(cond_state);
7765 if (cond_bye)
7766 mailimap_resp_cond_bye_free(cond_bye);
7767 if (mb_data)
7768 mailimap_mailbox_data_free(mb_data);
7769 if (msg_data)
7770 mailimap_message_data_free(msg_data);
7771 if (cap_data)
7772 mailimap_capability_data_free(cap_data);
7773 err:
7774 return res;
7775}
7776
7777/*
7778 response-done = response-tagged / response-fatal
7779*/
7780
7781static int
7782mailimap_response_done_parse(mailstream * fd, MMAPString * buffer,
7783 size_t * index,
7784 struct mailimap_response_done ** result,
7785 size_t progr_rate,
7786 progress_function * progr_fun)
7787{
7788 int type;
7789 struct mailimap_response_done * resp_done;
7790 size_t cur_token;
7791 struct mailimap_response_tagged * tagged;
7792 struct mailimap_response_fatal * fatal;
7793 int r;
7794 int res;
7795
7796 cur_token = * index;
7797
7798 tagged = NULL;
7799 fatal = NULL;
7800
7801 type = MAILIMAP_RESP_DONE_TYPE_ERROR; /* removes a gcc warning */
7802
7803 r = mailimap_response_tagged_parse(fd, buffer, &cur_token, &tagged,
7804 progr_rate, progr_fun);
7805 if (r == MAILIMAP_NO_ERROR)
7806 type = MAILIMAP_RESP_DONE_TYPE_TAGGED;
7807
7808 if (r == MAILIMAP_ERROR_PARSE) {
7809 r = mailimap_response_fatal_parse(fd, buffer, &cur_token, &fatal,
7810 progr_rate, progr_fun);
7811 if (r == MAILIMAP_NO_ERROR)
7812 type = MAILIMAP_RESP_DONE_TYPE_FATAL;
7813 }
7814
7815 if (r != MAILIMAP_NO_ERROR) {
7816 res = r;
7817 goto err;
7818 }
7819
7820 resp_done = mailimap_response_done_new(type, tagged, fatal);
7821 if (resp_done == NULL) {
7822 res = MAILIMAP_ERROR_MEMORY;
7823 goto free;
7824 }
7825
7826 * result = resp_done;
7827 * index = cur_token;
7828
7829 return MAILIMAP_NO_ERROR;
7830
7831 free:
7832 if (tagged == NULL)
7833 mailimap_response_tagged_free(tagged);
7834 if (fatal == NULL)
7835 mailimap_response_fatal_free(fatal);
7836 err:
7837 return res;
7838}
7839
7840/*
7841 response-fatal = "*" SP resp-cond-bye CRLF
7842 ; Server closes connection immediately
7843*/
7844
7845static int
7846mailimap_response_fatal_parse(mailstream * fd, MMAPString * buffer,
7847 size_t * index,
7848 struct mailimap_response_fatal ** result,
7849 size_t progr_rate,
7850 progress_function * progr_fun)
7851{
7852 struct mailimap_resp_cond_bye * cond_bye;
7853 struct mailimap_response_fatal * fatal;
7854 size_t cur_token;
7855 int res;
7856 int r;
7857
7858 cur_token = * index;
7859
7860 r = mailimap_star_parse(fd, buffer, &cur_token);
7861 if (r != MAILIMAP_NO_ERROR) {
7862 res = r;
7863 goto err;
7864 }
7865
7866 r = mailimap_space_parse(fd, buffer, &cur_token);
7867 if (r != MAILIMAP_NO_ERROR) {
7868 res = r;
7869 goto err;
7870 }
7871
7872 r = mailimap_resp_cond_bye_parse(fd, buffer, &cur_token, &cond_bye,
7873 progr_rate, progr_fun);
7874 if (r != MAILIMAP_NO_ERROR) {
7875 res = r;
7876 goto err;
7877 }
7878
7879 r = mailimap_crlf_parse(fd, buffer, &cur_token);
7880 if (r != MAILIMAP_NO_ERROR) {
7881 res = r;
7882 goto free;
7883 }
7884
7885 fatal = mailimap_response_fatal_new(cond_bye);
7886 if (fatal == NULL) {
7887 res = MAILIMAP_ERROR_MEMORY;
7888 goto free;
7889 }
7890
7891 * result = fatal;
7892 * index = cur_token;
7893
7894 return MAILIMAP_NO_ERROR;
7895
7896 free:
7897 mailimap_resp_cond_bye_free(cond_bye);
7898 err:
7899 return res;
7900}
7901
7902/*
7903 response-tagged = tag SP resp-cond-state CRLF
7904*/
7905
7906static int
7907mailimap_response_tagged_parse(mailstream * fd, MMAPString * buffer,
7908 size_t * index,
7909 struct mailimap_response_tagged ** result,
7910 size_t progr_rate,
7911 progress_function * progr_fun)
7912{
7913 size_t cur_token;
7914 char * tag;
7915 struct mailimap_resp_cond_state * cond_state;
7916 struct mailimap_response_tagged * resp_tagged;
7917 int r;
7918 int res;
7919
7920 cur_token = * index;
7921 cond_state = NULL;
7922
7923 r = mailimap_tag_parse(fd, buffer, &cur_token, &tag,
7924 progr_rate, progr_fun);
7925 if (r != MAILIMAP_NO_ERROR) {
7926 res = r;
7927 goto err;
7928 }
7929
7930 r = mailimap_space_parse(fd, buffer, &cur_token);
7931 if (r != MAILIMAP_NO_ERROR) {
7932 res = r;
7933 goto free_tag;
7934 }
7935
7936 r = mailimap_resp_cond_state_parse(fd, buffer, &cur_token, &cond_state,
7937 progr_rate, progr_fun);
7938 if (r != MAILIMAP_NO_ERROR) {
7939 res = r;
7940 goto free_tag;
7941 }
7942
7943 resp_tagged = mailimap_response_tagged_new(tag, cond_state);
7944 if (resp_tagged == NULL) {
7945 res = MAILIMAP_ERROR_MEMORY;
7946 goto free_cond_state;
7947 }
7948
7949 * result = resp_tagged;
7950 * index = cur_token;
7951
7952 return MAILIMAP_NO_ERROR;
7953
7954 free_cond_state:
7955 mailimap_resp_cond_state_free(cond_state);
7956 free_tag:
7957 mailimap_tag_free(tag);
7958 err:
7959 return res;
7960}
7961
7962/*
7963 resp-cond-auth = ("OK" / "PREAUTH") SP resp-text
7964 ; Authentication condition
7965*/
7966
7967static int
7968mailimap_resp_cond_auth_parse(mailstream * fd, MMAPString * buffer,
7969 size_t * index,
7970 struct mailimap_resp_cond_auth ** result,
7971 size_t progr_rate,
7972 progress_function * progr_fun)
7973{
7974 struct mailimap_resp_cond_auth * cond_auth;
7975 size_t cur_token;
7976 struct mailimap_resp_text * text;
7977 int type;
7978 int r;
7979 int res;
7980
7981 cur_token = * index;
7982 text = NULL;
7983
7984 type = MAILIMAP_RESP_COND_AUTH_ERROR; /* XXX - removes a gcc warning */
7985
7986 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "OK");
7987 if (r == MAILIMAP_NO_ERROR)
7988 type = MAILIMAP_RESP_COND_AUTH_OK;
7989
7990 if (r == MAILIMAP_ERROR_PARSE) {
7991 r = mailimap_token_case_insensitive_parse(fd, buffer,
7992 &cur_token, "PREAUTH");
7993 if (r == MAILIMAP_NO_ERROR)
7994 type = MAILIMAP_RESP_COND_AUTH_PREAUTH;
7995 }
7996
7997 if (r != MAILIMAP_NO_ERROR) {
7998 res = r;
7999 goto err;
8000 }
8001
8002 r = mailimap_space_parse(fd, buffer, &cur_token);
8003 if (r != MAILIMAP_NO_ERROR) {
8004 res = r;
8005 goto err;
8006 }
8007
8008 r = mailimap_resp_text_parse(fd, buffer, &cur_token, &text,
8009 progr_rate, progr_fun);
8010 if (r != MAILIMAP_NO_ERROR) {
8011 res = r;
8012 goto err;
8013 }
8014
8015 cond_auth = mailimap_resp_cond_auth_new(type, text);
8016 if (cond_auth == NULL) {
8017 res = MAILIMAP_ERROR_MEMORY;
8018 goto free;
8019 }
8020
8021 * result = cond_auth;
8022 * index = cur_token;
8023
8024 return MAILIMAP_NO_ERROR;
8025
8026 free:
8027 mailimap_resp_text_free(text);
8028 err:
8029 return res;
8030}
8031
8032/*
8033 resp-cond-bye = "BYE" SP resp-text
8034*/
8035
8036static int
8037mailimap_resp_cond_bye_parse(mailstream * fd, MMAPString * buffer,
8038 size_t * index,
8039 struct mailimap_resp_cond_bye ** result,
8040 size_t progr_rate,
8041 progress_function * progr_fun)
8042{
8043 size_t cur_token;
8044 struct mailimap_resp_cond_bye * cond_bye;
8045 struct mailimap_resp_text * text;
8046 int r;
8047 int res;
8048
8049 cur_token = * index;
8050
8051 r = mailimap_token_case_insensitive_parse(fd, buffer,
8052 &cur_token, "BYE");
8053 if (r != MAILIMAP_NO_ERROR) {
8054 res = r;
8055 goto err;
8056 }
8057
8058 r = mailimap_space_parse(fd, buffer, &cur_token);
8059 if (r != MAILIMAP_NO_ERROR) {
8060 res = r;
8061 goto err;
8062 }
8063
8064 r = mailimap_resp_text_parse(fd, buffer, &cur_token, &text,
8065 progr_rate, progr_fun);
8066 if (r != MAILIMAP_NO_ERROR) {
8067 res = r;
8068 goto err;
8069 }
8070
8071 cond_bye = mailimap_resp_cond_bye_new(text);
8072 if (cond_bye == NULL) {
8073 res = MAILIMAP_ERROR_MEMORY;
8074 goto free;
8075 }
8076
8077 * index = cur_token;
8078 * result = cond_bye;
8079
8080 return MAILIMAP_NO_ERROR;
8081
8082 free:
8083 mailimap_resp_text_free(text);
8084 err:
8085 return res;
8086}
8087
8088/*
8089 resp-cond-state = ("OK" / "NO" / "BAD") SP resp-text
8090 ; Status condition
8091*/
8092
8093static int
8094mailimap_resp_cond_state_parse(mailstream * fd, MMAPString * buffer,
8095 size_t * index,
8096 struct mailimap_resp_cond_state ** result,
8097 size_t progr_rate,
8098 progress_function * progr_fun)
8099{
8100 struct mailimap_resp_cond_state * cond_state;
8101 size_t cur_token;
8102 struct mailimap_resp_text * text;
8103 int type;
8104 int r;
8105 int res;
8106
8107 cur_token = * index;
8108 text = NULL;
8109
8110 type = mailimap_resp_cond_state_get_token_value(fd, buffer, &cur_token);
8111 if (type == -1) {
8112 res = MAILIMAP_ERROR_PARSE;
8113 goto err;
8114 }
8115
8116 r = mailimap_space_parse(fd, buffer, &cur_token);
8117 if (r != MAILIMAP_NO_ERROR) {
8118 res = r;
8119 goto err;
8120 }
8121
8122 r = mailimap_resp_text_parse(fd, buffer, &cur_token, &text,
8123 progr_rate, progr_fun);
8124 if (r != MAILIMAP_NO_ERROR) {
8125 res = r;
8126 goto err;
8127 }
8128
8129 cond_state = mailimap_resp_cond_state_new(type, text);
8130 if (cond_state == NULL) {
8131 res = MAILIMAP_ERROR_MEMORY;
8132 goto free;
8133 }
8134
8135 * result = cond_state;
8136 * index = cur_token;
8137
8138 return MAILIMAP_NO_ERROR;
8139
8140 free:
8141 mailimap_resp_text_free(text);
8142 err:
8143 return res;
8144}
8145
8146
8147/*
8148 resp-specials = "]"
8149*/
8150
8151static int is_resp_specials(char ch)
8152{
8153 switch (ch) {
8154 case ']':
8155 return TRUE;
8156 };
8157 return FALSE;
8158}
8159
8160/*
8161 resp-text = ["[" resp-text-code "]" SP] text
8162*/
8163
8164/* "[" resp-text-code "]" */
8165
8166static int
8167mailimap_resp_text_resp_text_code_parse(mailstream * fd, MMAPString * buffer,
8168 size_t * index,
8169 struct mailimap_resp_text_code **
8170 result,
8171 size_t progr_rate,
8172 progress_function * progr_fun)
8173{
8174 struct mailimap_resp_text_code * text_code;
8175 size_t cur_token;
8176 int r;
8177 int res;
8178
8179 cur_token = * index;
8180
8181 r = mailimap_obracket_parse(fd, buffer, &cur_token);
8182 if (r != MAILIMAP_NO_ERROR) {
8183 res = r;
8184 goto err;
8185 }
8186
8187 r = mailimap_resp_text_code_parse(fd, buffer, &cur_token, &text_code,
8188 progr_rate, progr_fun);
8189 if (r != MAILIMAP_NO_ERROR) {
8190 res = r;
8191 goto err;
8192 }
8193
8194 r = mailimap_cbracket_parse(fd, buffer, &cur_token);
8195 if (r != MAILIMAP_NO_ERROR) {
8196 res = r;
8197 goto free;
8198 }
8199
8200 r = mailimap_space_parse(fd, buffer, &cur_token);
8201 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
8202 res = r;
8203 goto free;
8204 }
8205
8206 * result = text_code;
8207 * index = cur_token;
8208
8209 return MAILIMAP_NO_ERROR;
8210
8211 free:
8212 mailimap_resp_text_code_free(text_code);
8213 err:
8214 return res;
8215}
8216
8217/*
8218 resp-text = ["[" resp-text-code "]" SP] text
8219*/
8220
8221static int
8222mailimap_resp_text_parse(mailstream * fd, MMAPString * buffer,
8223 size_t * index,
8224 struct mailimap_resp_text ** result,
8225 size_t progr_rate,
8226 progress_function * progr_fun)
8227{
8228 size_t cur_token;
8229 struct mailimap_resp_text_code * text_code;
8230 struct mailimap_resp_text * resp_text;
8231 char * text;
8232 int r;
8233 int res;
8234
8235 cur_token = * index;
8236 text = NULL;
8237 text_code = NULL;
8238
8239 r = mailimap_resp_text_resp_text_code_parse(fd, buffer, &cur_token,
8240 &text_code,
8241 progr_rate, progr_fun);
8242 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
8243 return r;
8244
8245 r = mailimap_text_parse(fd, buffer, &cur_token, &text,
8246 progr_rate, progr_fun);
8247 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
8248 res = r;
8249 goto free_resp_text_code;
8250 }
8251
8252 resp_text = mailimap_resp_text_new(text_code, text);
8253 if (resp_text == NULL) {
8254 res = MAILIMAP_ERROR_MEMORY;
8255 goto free_text;
8256 }
8257
8258 * result = resp_text;
8259 * index = cur_token;
8260
8261 return MAILIMAP_NO_ERROR;
8262
8263 free_resp_text_code:
8264 if (text_code != NULL)
8265 mailimap_resp_text_code_free(text_code);
8266 free_text:
8267 mailimap_text_free(text);
8268 return res;
8269}
8270
8271/*
8272 resp-text-code = "ALERT" /
8273 "BADCHARSET" [SP "(" astring *(SP astring) ")" ] /
8274 capability-data / "PARSE" /
8275 "PERMANENTFLAGS" SP "(" [flag-perm *(SP flag-perm)] ")" /
8276 "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
8277 "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
8278 "UNSEEN" SP nz-number /
8279 atom [SP 1*<any TEXT-CHAR except "]">]
8280*/
8281
8282/*
8283 ALERT / PARSE / READ-ONLY / READ-WRITE / TRYCREATE
8284*/
8285
8286static int
8287mailimap_resp_text_code_1_parse(mailstream * fd, MMAPString * buffer,
8288 size_t * index,
8289 int * result)
8290{
8291 int id;
8292 size_t cur_token;
8293
8294 cur_token = * index;
8295
8296 id = mailimap_resp_text_code_1_get_token_value(fd, buffer, &cur_token);
8297
8298 if (id == -1)
8299 return MAILIMAP_ERROR_PARSE;
8300
8301 * result = id;
8302 * index = cur_token;
8303
8304 return MAILIMAP_NO_ERROR;
8305}
8306
8307
8308/*
8309 "BADCHARSET" [SP "(" astring *(SP astring) ")" ]
8310*/
8311
8312/*
8313 SP "(" astring *(SP astring) ")"
8314*/
8315
8316static int
8317mailimap_resp_text_code_badcharset_1_parse(mailstream * fd,
8318 MMAPString * buffer,
8319 size_t * index,
8320 clist ** result,
8321 size_t progr_rate,
8322 progress_function * progr_fun)
8323{
8324 size_t cur_token;
8325 clist * charset;
8326 int r;
8327 int res;
8328
8329 cur_token = * index;
8330
8331 r = mailimap_space_parse(fd, buffer, &cur_token);
8332 if (r != MAILIMAP_NO_ERROR) {
8333 res = r;
8334 goto err;
8335 }
8336
8337 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
8338 if (r != MAILIMAP_NO_ERROR) {
8339 res = r;
8340 goto err;
8341 }
8342
8343 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, &charset,
8344 (mailimap_struct_parser *)
8345 mailimap_astring_parse,
8346 (mailimap_struct_destructor *)
8347 mailimap_astring_free,
8348 progr_rate, progr_fun);
8349 if (r != MAILIMAP_NO_ERROR) {
8350 res = r;
8351 goto err;
8352 }
8353
8354 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
8355 if (r != MAILIMAP_NO_ERROR) {
8356 res = r;
8357 goto charset;
8358 }
8359
8360 * index = cur_token;
8361 * result = charset;
8362
8363 return MAILIMAP_NO_ERROR;
8364
8365 charset:
8366 clist_foreach(charset, (clist_func) mailimap_string_free, NULL);
8367 clist_free(charset);
8368 err:
8369 return res;
8370}
8371
8372/*
8373 "BADCHARSET" [SP "(" astring *(SP astring) ")" ]
8374*/
8375
8376static int
8377mailimap_resp_text_code_badcharset_parse(mailstream * fd, MMAPString * buffer,
8378 size_t * index,
8379 clist ** result,
8380 size_t progr_rate,
8381 progress_function * progr_fun)
8382{
8383 size_t cur_token;
8384 clist * charset;
8385 int r;
8386
8387 cur_token = * index;
8388
8389 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
8390 "BADCHARSET");
8391 if (r != MAILIMAP_NO_ERROR)
8392 return r;
8393
8394 charset = NULL;
8395
8396 r = mailimap_resp_text_code_badcharset_1_parse(fd, buffer, &cur_token,
8397 &charset,
8398 progr_rate, progr_fun);
8399 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
8400 return r;
8401
8402 * result = charset;
8403 * index = cur_token;
8404
8405 return MAILIMAP_NO_ERROR;
8406}
8407
8408/*
8409 "PERMANENTFLAGS" SP "(" [flag-perm *(SP flag-perm)] ")"
8410*/
8411
8412static int
8413mailimap_resp_text_code_permanentflags_parse(mailstream * fd,
8414 MMAPString * buffer,
8415 size_t * index,
8416 clist ** result,
8417 size_t progr_rate,
8418 progress_function * progr_fun)
8419{
8420 size_t cur_token;
8421 clist * flaglist;
8422 int r;
8423 int res;
8424
8425 cur_token = * index;
8426
8427 flaglist = NULL;
8428
8429 r = mailimap_token_case_insensitive_parse(fd, buffer, &cur_token,
8430 "PERMANENTFLAGS");
8431 if (r != MAILIMAP_NO_ERROR) {
8432 res = r;
8433 goto err;
8434 }
8435
8436 r = mailimap_space_parse(fd, buffer, &cur_token);
8437 if (r != MAILIMAP_NO_ERROR) {
8438 res = r;
8439 goto err;
8440 }
8441
8442 r = mailimap_oparenth_parse(fd, buffer, &cur_token);
8443 if (r != MAILIMAP_NO_ERROR) {
8444 res = r;
8445 goto err;
8446 }
8447
8448 r = mailimap_struct_spaced_list_parse(fd, buffer, &cur_token, &flaglist,
8449 (mailimap_struct_parser *)
8450 mailimap_flag_perm_parse,
8451 (mailimap_struct_destructor *)
8452 mailimap_flag_perm_free,
8453 progr_rate, progr_fun);
8454 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
8455 res = r;
8456 goto err;
8457 }
8458
8459 r = mailimap_cparenth_parse(fd, buffer, &cur_token);
8460 if (r != MAILIMAP_NO_ERROR) {
8461 res = r;
8462 goto free;
8463 }
8464
8465 * index = cur_token;
8466 * result = flaglist;
8467
8468 return MAILIMAP_NO_ERROR;
8469
8470 free:
8471 clist_foreach(flaglist, (clist_func) mailimap_flag_perm_free, NULL);
8472 clist_free(flaglist);
8473 err:
8474 return res;
8475}
8476
8477
8478/*
8479 "UIDNEXT" SP nz-number /
8480 "UIDVALIDITY" SP nz-number /
8481 "UNSEEN" SP nz-number
8482*/
8483
8484static int
8485mailimap_resp_text_code_number_parse(mailstream * fd, MMAPString * buffer,
8486 size_t * index,
8487 struct mailimap_resp_text_code ** result,
8488 size_t progr_rate,
8489 progress_function * progr_fun)
8490{
8491 size_t cur_token;
8492 int type;
8493 uint32_t number;
8494 struct mailimap_resp_text_code * resp_text_code;
8495 int r;
8496
8497 cur_token = * index;
8498
8499 resp_text_code = NULL;
8500
8501 type = mailimap_resp_text_code_2_get_token_value(fd, buffer, &cur_token);
8502 if (type == -1)
8503 return MAILIMAP_ERROR_PARSE;
8504
8505 r = mailimap_space_parse(fd, buffer, &cur_token);
8506 if (r != MAILIMAP_NO_ERROR)
8507 return r;
8508
8509 r = mailimap_nz_number_parse(fd, buffer, &cur_token, &number);
8510 if (r != MAILIMAP_NO_ERROR)
8511 return r;
8512
8513 switch (type) {
8514 case MAILIMAP_RESP_TEXT_CODE_UIDNEXT:
8515 resp_text_code = mailimap_resp_text_code_new(type, NULL, NULL, NULL,
8516 number, 0, 0, NULL , NULL);
8517 break;
8518 case MAILIMAP_RESP_TEXT_CODE_UIDVALIDITY:
8519 resp_text_code = mailimap_resp_text_code_new(type, NULL, NULL, NULL,
8520 0, number, 0, NULL , NULL);
8521 break;
8522 case MAILIMAP_RESP_TEXT_CODE_UNSEEN:
8523 resp_text_code = mailimap_resp_text_code_new(type, NULL, NULL, NULL,
8524 0, 0, number, NULL , NULL);
8525 break;
8526 }
8527
8528 if (resp_text_code == NULL)
8529 return MAILIMAP_ERROR_MEMORY;
8530
8531 * result = resp_text_code;
8532 * index = cur_token;
8533
8534 return MAILIMAP_NO_ERROR;
8535}
8536
8537/*
8538 atom [SP 1*<any TEXT-CHAR except "]">]
8539*/
8540
8541static int is_text_char(char ch);
8542
8543/*
8544 any TEXT-CHAR except "]"
8545*/
8546
8547static int is_text_char_1(char ch)
8548{
8549 if (ch == ']')
8550 return FALSE;
8551 return is_text_char(ch);
8552}
8553
8554/*
8555 1*<any TEXT-CHAR except "]"
8556*/
8557
8558static int
8559mailimap_resp_text_code_other_2_parse(mailstream * fd, MMAPString * buffer,
8560 size_t * index, char ** result,
8561 size_t progr_rate,
8562 progress_function * progr_fun)
8563{
8564 return mailimap_custom_string_parse(fd, buffer, index, result,
8565 is_text_char_1);
8566}
8567
8568/*
8569 SP 1*<any TEXT-CHAR except "]">
8570*/
8571
8572static int
8573mailimap_resp_text_code_other_1_parse(mailstream * fd, MMAPString * buffer,
8574 size_t * index,
8575 char ** result,
8576 size_t progr_rate,
8577 progress_function * progr_fun)
8578{
8579 size_t cur_token;
8580 char * value;
8581 int r;
8582
8583 cur_token = * index;
8584
8585 r = mailimap_space_parse(fd, buffer, &cur_token);
8586 if (r != MAILIMAP_NO_ERROR)
8587 return r;
8588
8589 r = mailimap_resp_text_code_other_2_parse(fd, buffer, &cur_token,
8590 &value,
8591 progr_rate, progr_fun);
8592 if (r != MAILIMAP_NO_ERROR)
8593 return r;
8594
8595 * result = value;
8596 * index = cur_token;
8597
8598 return MAILIMAP_NO_ERROR;
8599}
8600
8601/*
8602 atom [SP 1*<any TEXT-CHAR except "]">]
8603*/
8604
8605static int
8606mailimap_resp_text_code_other_parse(mailstream * fd, MMAPString * buffer,
8607 size_t * index,
8608 struct mailimap_resp_text_code ** result,
8609 size_t progr_rate,
8610 progress_function * progr_fun)
8611{
8612 size_t cur_token;
8613 char * atom;
8614 char * value;
8615 struct mailimap_resp_text_code * resp_text_code;
8616 int r;
8617 int res;
8618
8619 cur_token = * index;
8620 atom = NULL;
8621 value = NULL;
8622
8623 r = mailimap_atom_parse(fd, buffer, &cur_token, &atom,
8624 progr_rate, progr_fun);
8625 if (r != MAILIMAP_NO_ERROR) {
8626 res = r;
8627 goto err;
8628 }
8629
8630 r = mailimap_resp_text_code_other_1_parse(fd, buffer, &cur_token,
8631 &value, progr_rate, progr_fun);
8632 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
8633 res = r;
8634 goto err;
8635 }
8636
8637 resp_text_code = mailimap_resp_text_code_new(MAILIMAP_RESP_TEXT_CODE_OTHER,
8638 NULL, NULL, NULL,
8639 0, 0, 0, atom, value);
8640 if (resp_text_code == NULL) {
8641 res = MAILIMAP_ERROR_MEMORY;
8642 goto free_value;
8643 }
8644
8645 * result = resp_text_code;
8646 * index = cur_token;
8647
8648 return MAILIMAP_NO_ERROR;
8649
8650 free_value:
8651 if (value != NULL)
8652 free(value);
8653 mailimap_atom_free(atom);
8654 err:
8655 return res;
8656}
8657
8658
8659
8660/*
8661 resp-text-code = "ALERT" /
8662 "BADCHARSET" [SP "(" astring *(SP astring) ")" ] /
8663 capability-data / "PARSE" /
8664 "PERMANENTFLAGS" SP "(" [flag-perm *(SP flag-perm)] ")" /
8665 "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
8666 "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
8667 "UNSEEN" SP nz-number /
8668 atom [SP 1*<any TEXT-CHAR except "]">]
8669*/
8670
8671static int
8672mailimap_resp_text_code_parse(mailstream * fd, MMAPString * buffer,
8673 size_t * index,
8674 struct mailimap_resp_text_code ** result,
8675 size_t progr_rate,
8676 progress_function * progr_fun)
8677{
8678 size_t cur_token;
8679 struct mailimap_resp_text_code * resp_text_code;
8680 clist * badcharset;
8681 clist * permanentflags;
8682 struct mailimap_capability_data * cap_data;
8683 int type;
8684 int r;
8685 int res;
8686
8687 cur_token = * index;
8688
8689 resp_text_code = NULL;
8690 badcharset = NULL;
8691 cap_data = NULL;
8692 permanentflags = NULL;
8693
8694 r = mailimap_resp_text_code_1_parse(fd, buffer, &cur_token, &type);
8695 if (r == MAILIMAP_NO_ERROR) {
8696 /* do nothing */
8697 }
8698
8699 if (r == MAILIMAP_ERROR_PARSE) {
8700
8701 r = mailimap_resp_text_code_badcharset_parse(fd, buffer, &cur_token,
8702 &badcharset,
8703 progr_rate, progr_fun);
8704 if (r == MAILIMAP_NO_ERROR)
8705 type = MAILIMAP_RESP_TEXT_CODE_BADCHARSET;
8706 }
8707
8708 if (r == MAILIMAP_ERROR_PARSE) {
8709
8710 r = mailimap_capability_data_parse(fd, buffer, &cur_token,
8711 &cap_data,
8712 progr_rate, progr_fun);
8713 if (r == MAILIMAP_NO_ERROR)
8714 type = MAILIMAP_RESP_TEXT_CODE_CAPABILITY_DATA;
8715 }
8716
8717 if (r == MAILIMAP_ERROR_PARSE) {
8718 r = mailimap_resp_text_code_permanentflags_parse(fd, buffer, &cur_token,
8719 &permanentflags,
8720 progr_rate,
8721 progr_fun);
8722 if (r == MAILIMAP_NO_ERROR)
8723 type = MAILIMAP_RESP_TEXT_CODE_PERMANENTFLAGS;
8724 }
8725
8726 if (r == MAILIMAP_ERROR_PARSE) {
8727 r = mailimap_resp_text_code_number_parse(fd, buffer, &cur_token,
8728 &resp_text_code,
8729 progr_rate, progr_fun);
8730 }
8731
8732 if (r == MAILIMAP_ERROR_PARSE) {
8733 r = mailimap_resp_text_code_other_parse(fd, buffer, &cur_token,
8734 &resp_text_code,
8735 progr_rate, progr_fun);
8736 }
8737
8738 if (r != MAILIMAP_NO_ERROR) {
8739 res = r;
8740 goto err;
8741 }
8742
8743 if (resp_text_code == NULL) {
8744 resp_text_code = mailimap_resp_text_code_new(type,
8745 badcharset, cap_data,
8746 permanentflags,
8747 0, 0, 0, NULL, NULL);
8748 if (resp_text_code == NULL) {
8749 res = MAILIMAP_ERROR_MEMORY;
8750 goto free;
8751 }
8752 }
8753
8754 * result = resp_text_code;
8755 * index = cur_token;
8756
8757 return MAILIMAP_NO_ERROR;
8758
8759free:
8760 if (permanentflags) {
8761 clist_foreach(permanentflags,
8762 (clist_func) mailimap_flag_perm_free, NULL);
8763 clist_free(permanentflags);
8764 }
8765 if (cap_data)
8766 mailimap_capability_data_free(cap_data);
8767 if (badcharset) {
8768 clist_foreach(badcharset, (clist_func) mailimap_astring_free, NULL);
8769 clist_free(badcharset);
8770 }
8771err:
8772 return res;
8773}
8774
8775/*
8776 UNIMPLEMENTED
8777 search = "SEARCH" [SP "CHARSET" SP astring] 1*(SP search-key)
8778 ; CHARSET argument to MUST be registered with IANA
8779*/
8780
8781/*
8782 UNIMPLEMENTED
8783 search-key = "ALL" / "ANSWERED" / "BCC" SP astring /
8784 "BEFORE" SP date / "BODY" SP astring /
8785 "CC" SP astring / "DELETED" / "FLAGGED" /
8786 "FROM" SP astring / "KEYWORD" SP flag-keyword / "NEW" /
8787 "OLD" / "ON" SP date / "RECENT" / "SEEN" /
8788 "SINCE" SP date / "SUBJECT" SP astring /
8789 "TEXT" SP astring / "TO" SP astring /
8790 "UNANSWERED" / "UNDELETED" / "UNFLAGGED" /
8791 "UNKEYWORD" SP flag-keyword / "UNSEEN" /
8792 ; Above this line were in [IMAP2]
8793 "DRAFT" / "HEADER" SP header-fld-name SP astring /
8794 "LARGER" SP number / "NOT" SP search-key /
8795 "OR" SP search-key SP search-key /
8796 "SENTBEFORE" SP date / "SENTON" SP date /
8797 "SENTSINCE" SP date / "SMALLER" SP number /
8798 "UID" SP set / "UNDRAFT" / set /
8799 "(" search-key *(SP search-key) ")"
8800*/
8801
8802/*
8803 section = "[" [section-spec] "]"
8804*/
8805
8806static int
8807mailimap_section_parse(mailstream * fd, MMAPString * buffer,
8808 size_t * index,
8809 struct mailimap_section ** result,
8810 size_t progr_rate,
8811 progress_function * progr_fun)
8812{
8813 struct mailimap_section_spec * section_spec;
8814 size_t cur_token;
8815 struct mailimap_section * section;
8816 int r;
8817 int res;
8818
8819 cur_token = * index;
8820
8821 section_spec = NULL;
8822
8823 r = mailimap_obracket_parse(fd, buffer, &cur_token);
8824 if (r != MAILIMAP_NO_ERROR) {
8825 res = r;
8826 goto err;
8827 }
8828
8829 r = mailimap_section_spec_parse(fd, buffer, &cur_token, &section_spec,
8830 progr_rate, progr_fun);
8831 if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE)) {
8832 res = r;
8833 goto err;
8834 }
8835
8836 r = mailimap_cbracket_parse(fd, buffer, &cur_token);
8837 if (r != MAILIMAP_NO_ERROR) {
8838 res = r;
8839 goto err;
8840 }
8841
8842 if (section_spec == NULL)
8843 section = NULL;
8844 else {
8845 section = mailimap_section_new(section_spec);
8846 if (section == NULL) {
8847 res = MAILIMAP_ERROR_MEMORY;
8848 goto free;
8849 }
8850 }
8851
8852 * result = section;
8853 * index = cur_token;
8854
8855 return MAILIMAP_NO_ERROR;
8856
8857 free:
8858 mailimap_section_spec_free(section_spec);
8859 err:
8860 return res;
8861}
8862
8863/*
8864 section-msgtext = "HEADER" / "HEADER.FIELDS" [".NOT"] SP header-list /
8865 "TEXT"
8866 ; top-level or MESSAGE/RFC822 part
8867*/
8868
8869static int
8870mailimap_section_msgtext_parse(mailstream * fd, MMAPString * buffer,
8871 size_t * index,
8872 struct mailimap_section_msgtext ** result,
8873 size_t progr_rate,
8874 progress_function * progr_fun)
8875{
8876 size_t cur_token;
8877 int type;
8878 struct mailimap_header_list * header_list;
8879 struct mailimap_section_msgtext * msgtext;
8880 int r;
8881 int res;
8882
8883 cur_token = * index;
8884
8885 header_list = NULL;
8886
8887 type = mailimap_section_msgtext_get_token_value(fd, buffer, &cur_token);
8888 if (type == -1) {
8889 res = MAILIMAP_ERROR_PARSE;
8890 goto err;
8891 }
8892
8893 if (type == MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS) {
8894 r = mailimap_header_list_parse(fd, buffer, &cur_token, &header_list,
8895 progr_rate, progr_fun);
8896 if (r != MAILIMAP_NO_ERROR) {
8897 res = r;
8898 goto err;
8899 }
8900 }
8901 else if (type == MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT) {
8902 r = mailimap_header_list_parse(fd, buffer, &cur_token, &header_list,
8903 progr_rate, progr_fun);
8904 if (r != MAILIMAP_NO_ERROR) {
8905 res = r;
8906 goto err;
8907 }
8908 }
8909
8910 msgtext = mailimap_section_msgtext_new(type, header_list);
8911 if (msgtext == NULL) {
8912 res = MAILIMAP_ERROR_MEMORY;
8913 goto free_header_list;
8914 }
8915
8916 * result = msgtext;
8917 * index = cur_token;
8918
8919 return MAILIMAP_NO_ERROR;
8920
8921 free_header_list:
8922 if (header_list)
8923 mailimap_header_list_free(header_list);
8924 err:
8925 return res;
8926}
8927
8928/*
8929 section-part = nz-number *("." nz-number)
8930 ; body part nesting
8931*/
8932
8933static int
8934mailimap_section_part_parse(mailstream * fd, MMAPString * buffer,
8935 size_t * index,
8936 struct mailimap_section_part ** result,
8937 size_t progr_rate,
8938 progress_function * progr_fun)
8939{
8940 struct mailimap_section_part * section_part;
8941 size_t cur_token;
8942 clist * section_id;
8943 int r;
8944 int res;
8945
8946 cur_token = * index;
8947 section_id = NULL;
8948
8949 r = mailimap_struct_list_parse(fd, buffer, &cur_token, &section_id, '.',
8950 (mailimap_struct_parser *)
8951 mailimap_nz_number_alloc_parse,
8952 (mailimap_struct_destructor *)
8953 mailimap_number_alloc_free,
8954 progr_rate, progr_fun);
8955 if (r != MAILIMAP_NO_ERROR) {
8956 res = r;
8957 goto err;
8958 }
8959
8960 section_part = mailimap_section_part_new(section_id);
8961 if (section_part == NULL) {
8962 res = MAILIMAP_ERROR_MEMORY;
8963 goto free_section_id;
8964 }
8965
8966 * result = section_part;
8967 * index = cur_token;
8968
8969 return MAILIMAP_NO_ERROR;
8970
8971 free_section_id:
8972 clist_foreach(section_id, (clist_func) mailimap_number_alloc_free, NULL);
8973 clist_free(section_id);
8974 err:
8975 return res;
8976}
8977
8978/*
8979 section-spec = section-msgtext / (section-part ["." section-text])
8980*/
8981
8982static int
8983mailimap_section_spec_parse(mailstream * fd, MMAPString * buffer,
8984 size_t * index,
8985 struct mailimap_section_spec ** result,
8986 size_t progr_rate,
8987 progress_function * progr_fun)
8988{
8989 int type;
8990 struct mailimap_section_msgtext * section_msgtext;
8991 struct mailimap_section_part * section_part;
8992 struct mailimap_section_text * section_text;
8993 struct mailimap_section_spec * section_spec;
8994 size_t cur_token;
8995 int r;
8996 int res;
8997 size_t final_token;
8998
8999 cur_token = * index;
9000
9001 section_msgtext = NULL;
9002 section_part = NULL;
9003 section_text = NULL;
9004
9005 r = mailimap_section_msgtext_parse(fd, buffer, &cur_token,
9006 &section_msgtext,
9007 progr_rate, progr_fun);
9008 switch (r) {
9009 case MAILIMAP_NO_ERROR:
9010 type = MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT;
9011 break;
9012
9013 case MAILIMAP_ERROR_PARSE:
9014
9015 r = mailimap_section_part_parse(fd, buffer, &cur_token,
9016 &section_part,
9017 progr_rate, progr_fun);
9018 if (r != MAILIMAP_NO_ERROR) {
9019 res = r;
9020 goto err;
9021 }
9022
9023 final_token = cur_token;
9024
9025 type = MAILIMAP_SECTION_SPEC_SECTION_PART;
9026
9027 r = mailimap_dot_parse(fd, buffer, &cur_token);
9028 if (r == MAILIMAP_NO_ERROR) {
9029 r = mailimap_section_text_parse(fd, buffer, &cur_token, &section_text,
9030 progr_rate, progr_fun);
9031 if (r == MAILIMAP_NO_ERROR) {
9032 final_token = cur_token;
9033 }
9034 else if (r != MAILIMAP_ERROR_PARSE) {
9035 res = r;
9036 goto err;
9037 }
9038 }
9039 else if (r != MAILIMAP_ERROR_PARSE) {
9040 res = r;
9041 goto err;
9042 }
9043
9044 cur_token = final_token;
9045 break;
9046
9047 default:
9048 res = r;
9049 goto err;
9050 }
9051
9052 section_spec = mailimap_section_spec_new(type, section_msgtext,
9053 section_part, section_text);
9054 if (section_spec == NULL) {
9055 res = MAILIMAP_ERROR_MEMORY;
9056 goto free;
9057 }
9058
9059 * result = section_spec;
9060 * index = cur_token;
9061
9062 return MAILIMAP_NO_ERROR;
9063
9064 free:
9065 if (section_msgtext)
9066 mailimap_section_msgtext_free(section_msgtext);
9067 if (section_part)
9068 mailimap_section_part_free(section_part);
9069 if (section_text)
9070 mailimap_section_text_free(section_text);
9071 err:
9072 return res;
9073}
9074
9075/*
9076 section-text = section-msgtext / "MIME"
9077 ; text other than actual body part (headers, etc.)
9078*/
9079
9080static int
9081mailimap_section_text_parse(mailstream * fd, MMAPString * buffer,
9082 size_t * index,
9083 struct mailimap_section_text ** result,
9084 size_t progr_rate,
9085 progress_function * progr_fun)
9086{
9087 struct mailimap_section_msgtext * section_msgtext;
9088 size_t cur_token;
9089 struct mailimap_section_text * section_text;
9090 int type;
9091 int r;
9092 int res;
9093
9094 cur_token = * index;
9095
9096 section_msgtext = NULL;
9097
9098 type = MAILIMAP_SECTION_TEXT_ERROR; /* XXX - removes a gcc warning */
9099
9100 r = mailimap_section_msgtext_parse(fd, buffer, &cur_token, &section_msgtext,
9101 progr_rate, progr_fun);
9102 if (r == MAILIMAP_NO_ERROR)
9103 type = MAILIMAP_SECTION_TEXT_SECTION_MSGTEXT;
9104
9105 if (r == MAILIMAP_ERROR_PARSE) {
9106 r= mailimap_token_case_insensitive_parse(fd, buffer, &cur_token, "MIME");
9107
9108 if (r == MAILIMAP_NO_ERROR)
9109 type = MAILIMAP_SECTION_TEXT_MIME;
9110 }
9111
9112 if (r != MAILIMAP_NO_ERROR) {
9113 res = r;
9114 goto err;
9115 }
9116
9117 section_text = mailimap_section_text_new(type, section_msgtext);
9118 if (section_text == NULL) {
9119 res = MAILIMAP_ERROR_MEMORY;
9120 goto free;
9121 }
9122
9123 * result = section_text;
9124 * index = cur_token;
9125
9126 return MAILIMAP_NO_ERROR;
9127
9128 free:
9129 if (section_msgtext)
9130 mailimap_section_msgtext_free(section_msgtext);
9131 err:
9132 return res;
9133}
9134
9135/*
9136 UNIMPLEMENTED
9137 select = "SELECT" SP mailbox
9138*/
9139
9140/*
9141 UNIMPLEMENTED
9142 sequence-num = nz-number / "*"
9143 ; * is the largest number in use. For message
9144 ; sequence numbers, it is the number of messages
9145 ; in the mailbox. For unique identifiers, it is
9146 ; the unique identifier of the last message in
9147 ; the mailbox.
9148*/
9149
9150/*
9151 UNIMPLEMENTED
9152 set = sequence-num / (sequence-num ":" sequence-num) /
9153 (set "," set)
9154 ; Identifies a set of messages. For message
9155 ; sequence numbers, these are consecutive
9156 ; numbers from 1 to the number of messages in
9157 ; the mailbox
9158 ; Comma delimits individual numbers, colon
9159 ; delimits between two numbers inclusive.
9160 ; Example: 2,4:7,9,12:* is 2,4,5,6,7,9,12,13,
9161 ; 14,15 for a mailbox with 15 messages.
9162*/
9163
9164/*
9165 UNIMPLEMENTED
9166 status = "STATUS" SP mailbox SP "(" status-att *(SP status-att) ")"
9167*/
9168
9169/*
9170 status-att = "MESSAGES" / "RECENT" / "UIDNEXT" / "UIDVALIDITY" /
9171 "UNSEEN"
9172*/
9173
9174static int mailimap_status_att_parse(mailstream * fd, MMAPString * buffer,
9175 size_t * index, int * result)
9176{
9177 int type;
9178 size_t cur_token;
9179
9180 cur_token = * index;
9181
9182 type = mailimap_status_att_get_token_value(fd, buffer, &cur_token);
9183
9184 if (type == -1)
9185 return MAILIMAP_ERROR_PARSE;
9186
9187 * result = type;
9188 * index = cur_token;
9189
9190 return MAILIMAP_NO_ERROR;
9191}
9192
9193
9194/*
9195 UNIMPLEMENTED
9196 store = "STORE" SP set SP store-att-flags
9197*/
9198
9199/*
9200 UNIMPLEMENTED
9201 store-att-flags = (["+" / "-"] "FLAGS" [".SILENT"]) SP
9202 (flag-list / (flag *(SP flag)))
9203*/
9204
9205/*
9206 string = quoted / literal
9207*/
9208
9209static int
9210mailimap_string_parse(mailstream * fd, MMAPString * buffer,
9211 size_t * index, char ** result,
9212 size_t * result_len,
9213 size_t progr_rate,
9214 progress_function * progr_fun)
9215{
9216 size_t cur_token;
9217 char * string;
9218 int r;
9219 size_t len;
9220
9221 cur_token = * index;
9222
9223 r = mailimap_quoted_parse(fd, buffer, &cur_token, &string,
9224 progr_rate, progr_fun);
9225 if (r == MAILIMAP_NO_ERROR)
9226 len = strlen(string);
9227 else if (r == MAILIMAP_ERROR_PARSE) {
9228 r = mailimap_literal_parse(fd, buffer, &cur_token, &string, &len,
9229 progr_rate, progr_fun);
9230 }
9231
9232 if (r != MAILIMAP_NO_ERROR)
9233 return r;
9234
9235 * result = string;
9236 if (result_len != NULL)
9237 * result_len = len;
9238 * index = cur_token;
9239
9240 return MAILIMAP_NO_ERROR;
9241}
9242
9243
9244/*
9245 UNIMPLEMENTED
9246 subscribe = "SUBSCRIBE" SP mailbox
9247*/
9248
9249/*
9250 tag = 1*<any ASTRING-CHAR except "+">
9251*/
9252
9253/*
9254 any ASTRING-CHAR except "+"
9255*/
9256
9257static int is_tag_char(char ch)
9258{
9259 if (ch == '+')
9260 return FALSE;
9261 return is_astring_char(ch);
9262}
9263
9264/*
9265 tag = 1*<any ASTRING-CHAR except "+">
9266*/
9267
9268static int mailimap_tag_parse(mailstream * fd, MMAPString * buffer,
9269 size_t * index, char ** result,
9270 size_t progr_rate,
9271 progress_function * progr_fun)
9272{
9273 size_t cur_token;
9274 char * tag;
9275 int r;
9276
9277 cur_token = * index;
9278
9279 r = mailimap_custom_string_parse(fd, buffer, &cur_token, &tag,
9280 is_tag_char);
9281 if (r != MAILIMAP_NO_ERROR)
9282 return r;
9283
9284 * index = cur_token;
9285 * result = tag;
9286
9287 return MAILIMAP_NO_ERROR;
9288}
9289
9290/*
9291 text = 1*TEXT-CHAR
9292*/
9293
9294static int mailimap_text_parse(mailstream * fd, MMAPString * buffer,
9295 size_t * index, char ** result,
9296 size_t progr_rate,
9297 progress_function * progr_fun)
9298{
9299 return mailimap_custom_string_parse(fd, buffer, index, result,
9300 is_text_char);
9301}
9302
9303
9304/*
9305 TEXT-CHAR = <any CHAR except CR and LF>
9306*/
9307
9308static int is_text_char(char ch)
9309{
9310 if ((ch == '\r') || (ch == '\n'))
9311 return FALSE;
9312
9313 return is_char(ch);
9314}
9315
9316/*
9317 time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
9318 ; Hours minutes seconds
9319*/
9320
9321/*
9322 2DIGIT
9323*/
9324
9325static int mailimap_2digit_parse(mailstream * fd, MMAPString * buffer,
9326 size_t * index, int * result)
9327{
9328#ifndef UNSTRICT_SYNTAX
9329 int digit;
9330 int two_digit;
9331 size_t cur_token;
9332 int r;
9333
9334 cur_token = * index;
9335
9336 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit);
9337 if (r != MAILIMAP_NO_ERROR)
9338 return r;
9339
9340 two_digit = digit;
9341
9342 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit);
9343 if (r != MAILIMAP_NO_ERROR)
9344 return r;
9345
9346 two_digit = two_digit * 10 + digit;
9347
9348 * result = two_digit;
9349 * index = cur_token;
9350
9351 return MAILIMAP_NO_ERROR;
9352#else
9353 uint32_t number;
9354 size_t cur_token;
9355 int r;
9356
9357 cur_token = * index;
9358
9359 r = mailimap_number_parse(fd, buffer, &cur_token, &number);
9360 if (r != MAILIMAP_NO_ERROR)
9361 return r;
9362
9363 * index = cur_token;
9364 * result = number;
9365
9366 return MAILIMAP_NO_ERROR;
9367#endif
9368}
9369
9370/*
9371 time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
9372 ; Hours minutes seconds
9373*/
9374
9375static int mailimap_time_parse(mailstream * fd, MMAPString * buffer,
9376 size_t * index,
9377 int * phour, int * pmin, int * psec)
9378{
9379 size_t cur_token;
9380 int hour;
9381 int min;
9382 int sec;
9383 int r;
9384
9385 cur_token = * index;
9386
9387 r = mailimap_2digit_parse(fd, buffer, &cur_token, &hour);
9388 if (r != MAILIMAP_NO_ERROR)
9389 return r;
9390
9391 r = mailimap_colon_parse(fd, buffer, &cur_token);
9392 if (r != MAILIMAP_NO_ERROR)
9393 return r;
9394
9395 r = mailimap_2digit_parse(fd, buffer, &cur_token, &min);
9396 if (r != MAILIMAP_NO_ERROR)
9397 return r;
9398
9399 r = mailimap_colon_parse(fd, buffer, &cur_token);
9400 if (r != MAILIMAP_NO_ERROR)
9401 return r;
9402
9403 r = mailimap_2digit_parse(fd, buffer, &cur_token, &sec);
9404 if (r != MAILIMAP_NO_ERROR)
9405 return r;
9406
9407 * phour = hour;
9408 * pmin = min;
9409 * psec = sec;
9410 * index = cur_token;
9411
9412 return MAILIMAP_NO_ERROR;
9413}
9414
9415/*
9416 UNIMPLEMENTED
9417 uid = "UID" SP (copy / fetch / search / store)
9418 ; Unique identifiers used instead of message
9419 ; sequence numbers
9420*/
9421
9422/*
9423 uniqueid = nz-number
9424 ; Strictly ascending
9425*/
9426
9427static int mailimap_uniqueid_parse(mailstream * fd, MMAPString * buffer,
9428 size_t * index, uint32_t * result)
9429{
9430 return mailimap_nz_number_parse(fd, buffer, index, result);
9431}
9432
9433/*
9434 UNIMPLEMENTED
9435 unsubscribe = "UNSUBSCRIBE" SP mailbox
9436*/
9437
9438/*
9439 UNIMPLEMENTED
9440 userid = astring
9441*/
9442
9443/*
9444 UNIMPLEMENTED
9445 x-command = "X" atom <experimental command arguments>
9446*/
9447
9448/*
9449 zone = ("+" / "-") 4DIGIT
9450 ; Signed four-digit value of hhmm representing
9451 ; hours and minutes east of Greenwich (that is,
9452 ; the amount that the given time differs from
9453 ; Universal Time). Subtracting the timezone
9454 ; from the given time will give the UT form.
9455 ; The Universal Time zone is "+0000".
9456*/
9457
9458static int mailimap_zone_parse(mailstream * fd, MMAPString * buffer,
9459 size_t * index, int * result)
9460{
9461 size_t cur_token;
9462 uint32_t zone;
9463#ifndef UNSTRICT_SYNTAX
9464 int i;
9465 int digit;
9466#endif
9467 int sign;
9468 int r;
9469
9470 cur_token = * index;
9471
9472 sign = 1;
9473 r = mailimap_plus_parse(fd, buffer, &cur_token);
9474 if (r == MAILIMAP_NO_ERROR)
9475 sign = 1;
9476
9477 if (r == MAILIMAP_ERROR_PARSE) {
9478 r = mailimap_minus_parse(fd, buffer, &cur_token);
9479 if (r == MAILIMAP_NO_ERROR)
9480 sign = -1;
9481 }
9482
9483 if (r != MAILIMAP_NO_ERROR)
9484 return r;
9485
9486#ifdef UNSTRICT_SYNTAX
9487 r = mailimap_number_parse(fd, buffer, &cur_token, &zone);
9488 if (r != MAILIMAP_NO_ERROR)
9489 return r;
9490#else
9491 zone = 0;
9492 for(i = 0 ; i < 4 ; i ++) {
9493 r = mailimap_digit_parse(fd, buffer, &cur_token, &digit);
9494 if (r != MAILIMAP_NO_ERROR)
9495 return r;
9496 zone = zone * 10 + digit;
9497 }
9498#endif
9499
9500 zone *= sign;
9501
9502 * result = zone;
9503 * index = cur_token;
9504
9505 return MAILIMAP_NO_ERROR;
9506}
diff --git a/kmicromail/libetpan/imap/mailimap_parser.h b/kmicromail/libetpan/imap/mailimap_parser.h
new file mode 100644
index 0000000..b1de75b
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_parser.h
@@ -0,0 +1,69 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_PARSER_H
37
38#define MAILIMAP_PARSER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mailimap_types.h"
45
46int mailimap_greeting_parse(mailstream * fd, MMAPString * buffer,
47 size_t * index,
48 struct mailimap_greeting ** result,
49 size_t progr_rate,
50 progress_function * progr_fun);
51
52int
53mailimap_response_parse(mailstream * fd, MMAPString * buffer,
54 size_t * index, struct mailimap_response ** result,
55 size_t progr_rate,
56 progress_function * progr_fun);
57
58int
59mailimap_continue_req_parse(mailstream * fd, MMAPString * buffer,
60 size_t * index,
61 struct mailimap_continue_req ** result,
62 size_t progr_rate,
63 progress_function * progr_fun);
64
65#ifdef __cplusplus
66}
67#endif
68
69#endif
diff --git a/kmicromail/libetpan/imap/mailimap_print.c b/kmicromail/libetpan/imap/mailimap_print.c
new file mode 100644
index 0000000..8a04348
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_print.c
@@ -0,0 +1,1615 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35#ifdef DEBUG
36#include "mailimap_print.h"
37
38#include <stdio.h>
39
40static void mailimap_body_fields_print(struct mailimap_body_fields *
41 body_fields);
42static void mailimap_envelope_print(struct mailimap_envelope * env);
43static void mailimap_body_print(struct mailimap_body * body);
44static void mailimap_body_fld_enc_print(struct mailimap_body_fld_enc *
45 fld_enc);
46
47static int indent_size = 0;
48
49static void indent()
50{
51 indent_size ++;
52}
53
54static void unindent()
55{
56 indent_size --;
57}
58
59static void print_indent()
60{
61 int i;
62
63 for (i = 0 ; i < indent_size ; i++)
64 printf(" ");
65}
66
67
68static void mailimap_body_fld_lang_print(struct mailimap_body_fld_lang *
69 fld_lang)
70{
71 clistiter * cur;
72
73 print_indent();
74 printf("body-fld-lang { ");
75
76 switch (fld_lang->lg_type) {
77 case MAILIMAP_BODY_FLD_LANG_SINGLE:
78 printf("%s ", fld_lang->lg_data.lg_single);
79 break;
80
81 case MAILIMAP_BODY_FLD_LANG_LIST:
82 for(cur = clist_begin(fld_lang->lg_data.lg_list) ;
83 cur != NULL ; cur = clist_next(cur)) {
84 char * lang;
85
86 lang = clist_content(cur);
87
88 printf("%s ", lang);
89 }
90 break;
91 }
92
93 print_indent();
94 printf("}\n");
95}
96
97static void
98mailimap_single_body_fld_param_print(struct mailimap_single_body_fld_param *
99 single)
100{
101 printf("(%s = %s)", single->pa_name, single->pa_value);
102}
103
104static void mailimap_body_fld_param_print(struct mailimap_body_fld_param *
105 fld_param)
106{
107 clistiter * cur;
108
109 print_indent();
110 printf("body-fld-param { ");
111
112 for(cur = clist_begin(fld_param->pa_list) ; cur != NULL ;
113 cur = clist_next(cur)) {
114 struct mailimap_single_body_fld_param * single;
115
116 single = clist_content(cur);
117
118 mailimap_single_body_fld_param_print(single);
119 printf(" ");
120 }
121 printf("\n");
122}
123
124static void mailimap_body_fld_dsp_print(struct mailimap_body_fld_dsp * fld_dsp)
125{
126 print_indent();
127 printf("body-fld-dsp {\n");
128 indent();
129
130 print_indent();
131 printf("name { %s }\n", fld_dsp->dsp_type);
132
133 mailimap_body_fld_param_print(fld_dsp->dsp_attributes);
134
135 unindent();
136 print_indent();
137 printf("}\n");
138}
139
140static void mailimap_body_extension_list_print(clist * ext_list);
141
142static void mailimap_body_extension_print(struct mailimap_body_extension * ext)
143{
144 print_indent();
145 printf("body-extention {\n");
146 indent();
147
148 switch (ext->ext_type) {
149 case MAILIMAP_BODY_EXTENSION_NSTRING:
150 print_indent();
151 printf("%s\n", ext->ext_data.ext_nstring);
152 break;
153 case MAILIMAP_BODY_EXTENSION_NUMBER:
154 print_indent();
155 printf("%i\n", ext->ext_data.ext_number);
156 break;
157 case MAILIMAP_BODY_EXTENSION_LIST:
158 mailimap_body_extension_list_print(ext->ext_data.ext_body_extension_list);
159 break;
160 }
161
162 unindent();
163 print_indent();
164 printf("}\n");
165
166}
167
168static void mailimap_body_extension_list_print(clist * ext_list)
169{
170 clistiter * cur;
171
172 print_indent();
173 printf("body-extention-list {\n");
174 indent();
175
176 for (cur = clist_begin(ext_list) ; cur != NULL ;
177 cur = clist_next(cur)) {
178 struct mailimap_body_extension * ext;
179
180 ext = clist_content(cur);
181
182 mailimap_body_extension_print(ext);
183 }
184
185 unindent();
186 print_indent();
187 printf("}");
188}
189
190static void mailimap_body_ext_1part_print(struct mailimap_body_ext_1part *
191 body_ext_1part)
192{
193 print_indent();
194 printf("body-type-1part {\n");
195 indent();
196
197 print_indent();
198 printf("md5 { %s }\n", body_ext_1part->bd_md5);
199 if (body_ext_1part->bd_disposition) {
200 mailimap_body_fld_dsp_print(body_ext_1part->bd_disposition);
201 if (body_ext_1part->bd_language) {
202 mailimap_body_fld_lang_print(body_ext_1part->bd_language);
203
204 if (body_ext_1part->bd_extension_list)
205 mailimap_body_extension_list_print(body_ext_1part->bd_extension_list);
206 }
207 }
208
209 unindent();
210 print_indent();
211 printf("}\n");
212}
213
214static void mailimap_body_type_text_print(struct mailimap_body_type_text *
215 body_type_text)
216{
217 print_indent();
218 printf("body-type-text {\n");
219 indent();
220
221 print_indent();
222 printf("media-text { %s }\n", body_type_text->bd_media_text);
223 mailimap_body_fields_print(body_type_text->bd_fields);
224 print_indent();
225 printf("lines { %i }\n", body_type_text->bd_lines);
226
227 unindent();
228 print_indent();
229 printf("}\n");
230}
231
232static void mailimap_body_type_msg_print(struct mailimap_body_type_msg *
233 body_type_msg)
234{
235 print_indent();
236 printf("body-type-msg {\n");
237 indent();
238
239 mailimap_body_fields_print(body_type_msg->bd_fields);
240 mailimap_envelope_print(body_type_msg->bd_envelope);
241 mailimap_body_print(body_type_msg->bd_body);
242
243 print_indent();
244 printf("lines { %i }\n", body_type_msg->bd_lines);
245
246 unindent();
247 print_indent();
248 printf("}\n");
249}
250
251
252static void mailimap_body_fld_enc_print(struct mailimap_body_fld_enc * fld_enc)
253{
254 print_indent();
255 printf("body-fld-enc { ");
256
257 switch (fld_enc->enc_type) {
258 case MAILIMAP_BODY_FLD_ENC_7BIT:
259 print_indent();
260 printf("7bit");
261 break;
262 case MAILIMAP_BODY_FLD_ENC_8BIT:
263 printf("8bit");
264 break;
265 case MAILIMAP_BODY_FLD_ENC_BINARY:
266 printf("binary");
267 break;
268 case MAILIMAP_BODY_FLD_ENC_BASE64:
269 printf("base64");
270 break;
271 case MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE:
272 printf("quoted-printable");
273 break;
274 case MAILIMAP_BODY_FLD_ENC_OTHER:
275 printf("%s", fld_enc->enc_value);
276 break;
277 }
278
279 printf("}\n");
280}
281
282static void mailimap_body_fields_print(struct mailimap_body_fields *
283 body_fields)
284{
285 print_indent();
286 printf("body-fields {\n");
287 indent();
288
289 mailimap_body_fld_param_print(body_fields->bd_parameter);
290
291 print_indent();
292 printf("body-fld-id { %s }\n", body_fields->bd_id);
293 printf("body-fld-desc { %s }\n", body_fields->bd_description);
294 mailimap_body_fld_enc_print(body_fields->bd_encoding);
295 printf("body-fld-octets { %i }\n", body_fields->bd_size);
296
297 unindent();
298 print_indent();
299 printf("}\n");
300}
301
302static void mailimap_media_basic_print(struct mailimap_media_basic *
303 media_basic)
304{
305 print_indent();
306 printf("media-basic {");
307
308 switch (media_basic->med_type) {
309 case MAILIMAP_MEDIA_BASIC_APPLICATION:
310 printf("application");
311 break;
312 case MAILIMAP_MEDIA_BASIC_AUDIO:
313 printf("audio");
314 break;
315 case MAILIMAP_MEDIA_BASIC_IMAGE:
316 printf("image");
317 break;
318 case MAILIMAP_MEDIA_BASIC_MESSAGE:
319 printf("message");
320 break;
321 case MAILIMAP_MEDIA_BASIC_VIDEO:
322 printf("video");
323 break;
324 case MAILIMAP_MEDIA_BASIC_OTHER:
325 printf("%s", media_basic->med_basic_type);
326 break;
327 }
328 printf(" / %s }\n", media_basic->med_subtype);
329}
330
331static void mailimap_body_type_basic_print(struct mailimap_body_type_basic *
332 body_type_basic)
333{
334 print_indent();
335 printf("body-type-basic {\n");
336 indent();
337
338 mailimap_media_basic_print(body_type_basic->bd_media_basic);
339 mailimap_body_fields_print(body_type_basic->bd_fields);
340
341 unindent();
342 print_indent();
343 printf("}\n");
344}
345
346static void mailimap_body_type_1part_print(struct mailimap_body_type_1part *
347 body_type_1part)
348{
349 print_indent();
350 printf("body-type-1part {\n");
351 indent();
352
353 switch (body_type_1part->bd_type) {
354 case MAILIMAP_BODY_TYPE_1PART_BASIC:
355 mailimap_body_type_basic_print(body_type_1part->bd_data.bd_type_basic);
356 break;
357
358 case MAILIMAP_BODY_TYPE_1PART_MSG:
359 mailimap_body_type_msg_print(body_type_1part->bd_data.bd_type_msg);
360 break;
361
362 case MAILIMAP_BODY_TYPE_1PART_TEXT:
363 mailimap_body_type_text_print(body_type_1part->bd_data.bd_type_text);
364 break;
365 }
366
367 if (body_type_1part->bd_ext_1part != NULL)
368 mailimap_body_ext_1part_print(body_type_1part->bd_ext_1part);
369
370 unindent();
371 print_indent();
372 printf("\n");
373}
374
375static void mailimap_body_ext_mpart(struct mailimap_body_ext_mpart * ext_mpart)
376{
377 print_indent();
378 printf("body-ext-mpart {\n");
379 indent();
380
381 mailimap_body_fld_param_print(ext_mpart->bd_parameter);
382 if (ext_mpart->bd_disposition) {
383 mailimap_body_fld_dsp_print(ext_mpart->bd_disposition);
384 if (ext_mpart->bd_language) {
385 mailimap_body_fld_lang_print(ext_mpart->bd_language);
386
387 if (ext_mpart->bd_extension_list)
388 mailimap_body_extension_list_print(ext_mpart->bd_extension_list);
389 }
390 }
391
392 unindent();
393 print_indent();
394 printf("\n");
395}
396
397static void mailimap_body_type_mpart_print(struct mailimap_body_type_mpart *
398 mpart)
399{
400 clistiter * cur;
401
402 print_indent();
403 printf("body-type-mpart {\n");
404 indent();
405
406 for(cur = clist_begin(mpart->bd_list) ; cur != NULL ;
407 cur = clist_next(cur)) {
408 struct mailimap_body * body;
409
410 body = clist_content(cur);
411
412 mailimap_body_print(body);
413 }
414
415 printf("media-subtype { %s }\n", mpart->bd_media_subtype);
416
417 if (mpart->bd_ext_mpart)
418 mailimap_body_ext_mpart(mpart->bd_ext_mpart);
419
420 unindent();
421 print_indent();
422 printf("}\n");
423}
424
425
426static void mailimap_body_print(struct mailimap_body * body)
427{
428 print_indent();
429 printf("body {\n");
430 indent();
431
432 switch (body->bd_type) {
433 case MAILIMAP_BODY_1PART:
434 mailimap_body_type_1part_print(body->bd_data.bd_body_1part);
435 break;
436 case MAILIMAP_BODY_MPART:
437 mailimap_body_type_mpart_print(body->bd_data.bd_body_mpart);
438 break;
439 }
440
441 unindent();
442 print_indent();
443 printf("}\n");
444}
445
446static void mailimap_date_time_print(struct mailimap_date_time * date_time)
447{
448 print_indent();
449 printf("date-time { %i/%i/%i - %i:%i:%i %i }\n",
450 date_time->dt_day, date_time->dt_month, date_time->dt_year,
451 date_time->dt_hour, date_time->dt_min, date_time->dt_month,
452 date_time->dt_zone);
453}
454
455static void mailimap_address_print(struct mailimap_address * address)
456{
457 print_indent();
458 printf("address { name: %s, addr: %s, mailbox: %s, host: %s) }\n",
459 address->ad_personal_name, address->ad_source_route,
460 address->ad_mailbox_name, address->ad_host_name);
461}
462
463static void mailimap_envelope_address_list_print(clist * address)
464{
465 clistiter * cur;
466
467 print_indent();
468 printf("envelope-address-list {\n");
469 indent();
470
471 for(cur = clist_begin(address) ; cur != NULL ;
472 cur = clist_next(cur)) {
473 struct mailimap_address * addr;
474
475 addr = clist_content(cur);
476
477 mailimap_address_print(addr);
478 }
479
480 unindent();
481 print_indent();
482 printf("}\n");
483}
484
485static void mailimap_envelope_print(struct mailimap_envelope * env)
486{
487 print_indent();
488 printf("envelope {\n");
489 indent();
490
491 print_indent();
492 printf("date { %s }\n", env->env_date);
493
494 print_indent();
495 printf("subject { %s }\n", env->env_subject);
496
497 print_indent();
498 printf("from {\n");
499 indent();
500 mailimap_envelope_address_list_print(env->env_from->frm_list);
501 unindent();
502 print_indent();
503 printf("}\n");
504
505 print_indent();
506 printf("sender {\n");
507 indent();
508 mailimap_envelope_address_list_print(env->env_sender->snd_list);
509 unindent();
510 print_indent();
511 printf("}\n");
512
513 print_indent();
514 printf("reply-to {\n");
515 indent();
516 mailimap_envelope_address_list_print(env->env_reply_to->rt_list);
517 unindent();
518 print_indent();
519 printf("}\n");
520
521 print_indent();
522 printf("to {\n");
523 indent();
524 mailimap_envelope_address_list_print(env->env_to->to_list);
525 unindent();
526 print_indent();
527 printf("}\n");
528
529 print_indent();
530 printf("cc {\n");
531 indent();
532 mailimap_envelope_address_list_print(env->env_cc->cc_list);
533 unindent();
534 print_indent();
535 printf("}\n");
536
537 print_indent();
538 printf("bcc {\n");
539 indent();
540 mailimap_envelope_address_list_print(env->env_bcc->bcc_list);
541 unindent();
542 print_indent();
543 printf("}\n");
544
545 printf("in-reply-to { %s }\n", env->env_in_reply_to);
546 printf("message-id { %s }\n", env->env_message_id);
547
548 unindent();
549 print_indent();
550 printf("}\n");
551}
552
553static void mailimap_header_list_print(struct mailimap_header_list *
554 header_list)
555{
556 clistiter * cur;
557
558 print_indent();
559 printf("header-list { ");
560 for(cur = clist_begin(header_list->hdr_list) ; cur != NULL ;
561 cur = clist_next(cur))
562 printf("%s ", (char *) clist_content(cur));
563 printf("}\n");
564}
565
566static void mailimap_section_msgtext_print(struct mailimap_section_msgtext *
567 section_msgtext)
568{
569 print_indent();
570 printf("section-msgtext {\n");
571 indent();
572
573 switch(section_msgtext->sec_type) {
574 case MAILIMAP_SECTION_MSGTEXT_HEADER:
575 print_indent();
576 printf("header\n");
577 break;
578
579 case MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS:
580 print_indent();
581 printf("header fields {");
582 indent();
583 mailimap_header_list_print(section_msgtext->sec_header_list);
584 unindent();
585 print_indent();
586 printf("}\n");
587 break;
588
589 case MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT:
590 print_indent();
591 printf("header fields not {");
592 indent();
593 mailimap_header_list_print(section_msgtext->sec_header_list);
594 unindent();
595 print_indent();
596 printf("}\n");
597 break;
598
599 case MAILIMAP_SECTION_MSGTEXT_TEXT:
600 print_indent();
601 printf("text\n");
602 break;
603 }
604
605 unindent();
606 print_indent();
607 printf("}\n");
608}
609
610static void mailimap_section_part_print(struct mailimap_section_part *
611 section_part)
612{
613 clistiter * cur;
614
615 print_indent();
616 printf("section-part { ");
617
618 for(cur = clist_begin(section_part->sec_id) ;
619 cur != NULL ; cur = clist_next(cur)) {
620 printf("%i", * ((uint32_t *) clist_content(cur)));
621 if (clist_next(cur) != NULL)
622 printf(".");
623 }
624 printf(" }\n");
625}
626
627static void mailimap_section_text_print(struct mailimap_section_text *
628 section_text)
629{
630 print_indent();
631 printf("section-text {\n");
632 indent();
633
634 switch (section_text->sec_type) {
635 case MAILIMAP_SECTION_TEXT_MIME:
636 print_indent();
637 printf("MIME");
638 break;
639 case MAILIMAP_SECTION_TEXT_SECTION_MSGTEXT:
640 mailimap_section_msgtext_print(section_text->sec_msgtext);
641 break;
642 }
643
644 unindent();
645 print_indent();
646 printf("}\n");
647}
648
649static void mailimap_section_spec_print(struct mailimap_section_spec *
650 section_spec)
651{
652 print_indent();
653 printf("section-spec {");
654 indent();
655
656 switch(section_spec->sec_type) {
657 case MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT:
658 mailimap_section_msgtext_print(section_spec->sec_data.sec_msgtext);
659 break;
660 case MAILIMAP_SECTION_SPEC_SECTION_PART:
661 mailimap_section_part_print(section_spec->sec_data.sec_part);
662 if (section_spec->sec_text != NULL)
663 mailimap_section_text_print(section_spec->sec_text);
664 break;
665 }
666
667 unindent();
668 print_indent();
669 printf("}\n");
670}
671
672static void mailimap_section_print(struct mailimap_section * section)
673{
674 print_indent();
675 printf("section {\n");
676 indent();
677
678 if (section != NULL)
679 if (section->sec_spec != NULL)
680 mailimap_section_spec_print(section->sec_spec);
681
682 unindent();
683 print_indent();
684 printf("}\n");
685}
686
687static void mailimap_msg_att_body_section_print(struct
688 mailimap_msg_att_body_section *
689 msg_att_body_section)
690{
691 print_indent();
692 printf("msg-att-body-section {\n");
693 indent();
694
695 mailimap_section_print(msg_att_body_section->sec_section);
696 printf("origin-octet: %i\n", msg_att_body_section->sec_origin_octet);
697 printf("body-part: %s\n", msg_att_body_section->sec_body_part);
698
699 unindent();
700 print_indent();
701 printf("}\n");
702}
703
704
705static void mailimap_msg_att_static_print(struct mailimap_msg_att_static *
706 msg_att_static)
707{
708 print_indent();
709 printf("msg-att-static {\n");
710 indent();
711
712 switch (msg_att_static->att_type) {
713
714 case MAILIMAP_MSG_ATT_ENVELOPE:
715 print_indent();
716 printf("envelope {\n");
717 indent();
718 print_indent();
719 mailimap_envelope_print(msg_att_static->att_data.att_env);
720 unindent();
721 print_indent();
722 printf("}\n");
723 break;
724
725 case MAILIMAP_MSG_ATT_INTERNALDATE:
726 print_indent();
727 printf("internaldate {\n");
728 indent();
729 print_indent();
730 mailimap_date_time_print(msg_att_static->att_data.att_internal_date);
731 unindent();
732 print_indent();
733 printf("}\n");
734 break;
735
736 case MAILIMAP_MSG_ATT_RFC822:
737 print_indent();
738 printf("rfc822 {\n");
739 printf("%s\n", msg_att_static->att_data.att_rfc822.att_content);
740 print_indent();
741 printf("}\n");
742 break;
743
744 case MAILIMAP_MSG_ATT_RFC822_HEADER:
745 print_indent();
746 printf("rfc822-header {\n");
747 printf("%s\n", msg_att_static->att_data.att_rfc822_header.att_content);
748 print_indent();
749 printf("}\n");
750 break;
751
752 case MAILIMAP_MSG_ATT_RFC822_TEXT:
753 print_indent();
754 printf("rfc822-text {\n");
755 printf("%s\n", msg_att_static->att_data.att_rfc822_text.att_content);
756 print_indent();
757 printf("}\n");
758 break;
759
760 case MAILIMAP_MSG_ATT_RFC822_SIZE:
761 print_indent();
762 printf("rfc822-size { %i }\n", msg_att_static->att_data.att_rfc822_size);
763 break;
764
765 case MAILIMAP_MSG_ATT_BODY:
766 print_indent();
767 printf("body {\n");
768 indent();
769 print_indent();
770 mailimap_body_print(msg_att_static->att_data.att_body);
771 unindent();
772 print_indent();
773 printf("}\n");
774 break;
775
776 case MAILIMAP_MSG_ATT_BODYSTRUCTURE:
777 print_indent();
778 printf("bodystructure {\n");
779 indent();
780 print_indent();
781 mailimap_body_print(msg_att_static->att_data.att_bodystructure);
782 unindent();
783 print_indent();
784 printf("}\n");
785 break;
786
787 case MAILIMAP_MSG_ATT_BODY_SECTION:
788 print_indent();
789 printf("body-section {\n");
790 indent();
791 print_indent();
792 mailimap_msg_att_body_section_print(msg_att_static->att_data.att_body_section);
793 unindent();
794 print_indent();
795 printf("}\n");
796 break;
797
798 case MAILIMAP_MSG_ATT_UID:
799 printf("uid { %i }\n", msg_att_static->att_data.att_uid);
800 break;
801 }
802
803 unindent();
804 print_indent();
805 printf("}\n");
806}
807
808static void mailimap_flag_print(struct mailimap_flag * flag);
809
810static void mailimap_flag_fetch_print(struct mailimap_flag_fetch * flag)
811{
812 print_indent();
813 printf("flag fetch {\n");
814 indent();
815
816 switch (flag->fl_type) {
817 case MAILIMAP_FLAG_FETCH_RECENT:
818 printf("recent\n");
819 break;
820 case MAILIMAP_FLAG_FETCH_OTHER:
821 print_indent();
822 printf("flag {\n");
823 indent();
824 mailimap_flag_print(flag->fl_flag);
825 unindent();
826 print_indent();
827 printf("}\n");
828 break;
829 }
830
831 unindent();
832 print_indent();
833 printf("}\n");
834}
835
836static void mailimap_msg_att_dynamic_print(struct mailimap_msg_att_dynamic *
837 dynamic)
838{
839 clistiter * cur;
840
841 print_indent();
842 printf("msg-att-dynamic {\n");
843 indent();
844
845 for(cur = clist_begin(dynamic->att_list) ; cur != NULL ;
846 cur = clist_next(cur)) {
847 struct mailimap_flag_fetch * flag;
848
849 flag = (struct mailimap_flag_fetch *) clist_content(cur);
850 mailimap_flag_fetch_print(flag);
851 }
852
853 unindent();
854 print_indent();
855 printf("}\n");
856}
857
858static void mailimap_msg_att_item_print(struct mailimap_msg_att_item * item)
859{
860 print_indent();
861 printf("msg-att-item {\n");
862 indent();
863
864 switch (item->att_type) {
865 case MAILIMAP_MSG_ATT_ITEM_DYNAMIC:
866 mailimap_msg_att_dynamic_print(item->att_data.att_dyn);
867 break;
868 case MAILIMAP_MSG_ATT_ITEM_STATIC:
869 mailimap_msg_att_static_print(item->att_data.att_static);
870 break;
871 }
872
873 unindent();
874 print_indent();
875 printf("}\n");
876}
877
878static void mailimap_msg_att_print(struct mailimap_msg_att * msg_att)
879{
880 clistiter * cur;
881
882 print_indent();
883 printf("msg-att {\n");
884 indent();
885
886 for(cur = clist_begin(msg_att->att_list) ; cur != NULL ;
887 cur = clist_next(cur)) {
888 struct mailimap_msg_att_item * item;
889
890 item = clist_content(cur);
891
892 mailimap_msg_att_item_print(item);
893 }
894
895 unindent();
896 print_indent();
897 printf("}\n");
898}
899
900static void mailimap_message_data_print(struct mailimap_message_data *
901 msg_data)
902{
903 print_indent();
904 printf("message-data {\n");
905 indent();
906
907 switch (msg_data->mdt_type) {
908 case MAILIMAP_MESSAGE_DATA_EXPUNGE:
909 print_indent();
910 printf("expunged { %i }\n", msg_data->mdt_number);
911 break;
912 case MAILIMAP_MESSAGE_DATA_FETCH:
913 print_indent();
914 printf("message-number { %i }\n", msg_data->mdt_number);
915 mailimap_msg_att_print(msg_data->mdt_msg_att);
916 break;
917 }
918
919 unindent();
920 print_indent();
921 printf("}\n");
922}
923
924static void mailimap_status_att_print(int status_att)
925{
926 print_indent();
927 printf("status-att { ");
928
929 switch(status_att) {
930 case MAILIMAP_STATUS_ATT_MESSAGES:
931 printf("messages");
932 break;
933 case MAILIMAP_STATUS_ATT_RECENT:
934 printf("recent");
935 break;
936 case MAILIMAP_STATUS_ATT_UIDNEXT:
937 printf("uidnext");
938 break;
939 case MAILIMAP_STATUS_ATT_UIDVALIDITY:
940 printf("status att uidvalidity");
941 break;
942 case MAILIMAP_STATUS_ATT_UNSEEN:
943 printf("status att unseen");
944 break;
945 }
946
947 printf(" \n");
948}
949
950static void
951mailimap_status_info_print(struct mailimap_status_info * info)
952{
953 print_indent();
954 printf("status-info {\n");
955 indent();
956
957 mailimap_status_att_print(info->st_att);
958
959 print_indent();
960 printf("value { %i }\n", info->st_value);
961
962 unindent();
963 print_indent();
964 printf("}\n");
965}
966
967static void
968mailimap_mailbox_data_status_print(struct mailimap_mailbox_data_status *
969 mb_data_status)
970{
971 clistiter * cur;
972
973 print_indent();
974 printf("mailbox-data-status {\n");
975 indent();
976
977 print_indent();
978 printf("mailbox { %s }\n", mb_data_status->st_mailbox);
979
980 for(cur = clist_begin(mb_data_status->st_info_list) ;
981 cur != NULL ; cur = clist_next(cur)) {
982 struct mailimap_status_info * info;
983
984 info = clist_content(cur);
985
986 mailimap_status_info_print(info);
987 }
988
989 unindent();
990 print_indent();
991 printf("}\n");
992}
993
994static void mailimap_mbx_list_oflag_print(struct mailimap_mbx_list_oflag *
995 oflag)
996{
997 print_indent();
998 printf("mbx-list-oflag { ");
999
1000 switch (oflag->of_type) {
1001 case MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS:
1002 printf("noinferiors");
1003 break;
1004 case MAILIMAP_MBX_LIST_OFLAG_FLAG_EXT:
1005 printf("%s", oflag->of_flag_ext);
1006 break;
1007 }
1008
1009 printf(" }\n");
1010}
1011
1012static void mailimap_mbx_list_sflag_print(int sflag)
1013{
1014 print_indent();
1015 printf("mbx-list-sflag { ");
1016
1017 switch (sflag) {
1018 case MAILIMAP_MBX_LIST_SFLAG_MARKED:
1019 printf("marked");
1020 break;
1021 case MAILIMAP_MBX_LIST_SFLAG_NOSELECT:
1022 printf("noselected");
1023 break;
1024 case MAILIMAP_MBX_LIST_SFLAG_UNMARKED:
1025 printf("unmarked");
1026 break;
1027 }
1028
1029 printf(" }\n");
1030}
1031
1032static void mailimap_mbx_list_flags_print(struct mailimap_mbx_list_flags *
1033 mbx_list_flags)
1034{
1035 clistiter * cur;
1036
1037 print_indent();
1038 printf("mbx-list-flags {");
1039 indent();
1040
1041 if (mbx_list_flags->mbf_type == MAILIMAP_MBX_LIST_FLAGS_SFLAG)
1042 mailimap_mbx_list_sflag_print(mbx_list_flags->mbf_sflag);
1043
1044 for(cur = clist_begin(mbx_list_flags->mbf_oflags) ; cur != NULL ;
1045 cur = clist_next(cur)) {
1046 struct mailimap_mbx_list_oflag * oflag;
1047
1048 oflag = clist_content(cur);
1049
1050 mailimap_mbx_list_oflag_print(oflag);
1051 }
1052
1053 unindent();
1054 print_indent();
1055 printf("}\n");
1056}
1057
1058static void mailimap_mailbox_list_print(struct mailimap_mailbox_list * mb_list)
1059{
1060 print_indent();
1061 printf("mailbox-list {\n");
1062 indent();
1063
1064 mailimap_mbx_list_flags_print(mb_list->mb_flag);
1065 printf("dir-separator { %c }\n", mb_list->mb_delimiter);
1066 printf("mailbox { %s }\n", mb_list->mb_name);
1067
1068 unindent();
1069 print_indent();
1070 printf("}\n");
1071}
1072
1073static void mailimap_flag_list_print(struct mailimap_flag_list * flag_list)
1074{
1075 clistiter * cur;
1076
1077 print_indent();
1078 printf("flag-list {\n");
1079 indent();
1080
1081 for(cur = clist_begin(flag_list->fl_list) ; cur != NULL ;
1082 cur = clist_next(cur)) {
1083 struct mailimap_flag * flag;
1084
1085 flag = clist_content(cur);
1086
1087 print_indent();
1088 mailimap_flag_print(flag);
1089 printf("\n");
1090 }
1091
1092 unindent();
1093 print_indent();
1094 printf("}\n");
1095}
1096
1097
1098static void mailimap_mailbox_data_print(struct mailimap_mailbox_data * mb_data)
1099{
1100 clistiter * cur;
1101
1102 print_indent();
1103 printf("mailbox-data {\n");
1104 indent();
1105
1106 switch (mb_data->mbd_type) {
1107 case MAILIMAP_MAILBOX_DATA_FLAGS:
1108 print_indent();
1109 printf("flags {\n");
1110 indent();
1111 mailimap_flag_list_print(mb_data->mbd_data.mbd_flags);
1112 unindent();
1113 print_indent();
1114 printf("}\n");
1115 break;
1116
1117 case MAILIMAP_MAILBOX_DATA_LIST:
1118 print_indent();
1119 printf("list {\n");
1120 indent();
1121 mailimap_mailbox_list_print(mb_data->mbd_data.mbd_list);
1122 unindent();
1123 print_indent();
1124 printf("}\n");
1125 break;
1126
1127 case MAILIMAP_MAILBOX_DATA_LSUB:
1128 print_indent();
1129 printf("lsub {\n");
1130 indent();
1131 mailimap_mailbox_list_print(mb_data->mbd_data.mbd_lsub);
1132 unindent();
1133 print_indent();
1134 printf("}\n");
1135 break;
1136
1137 case MAILIMAP_MAILBOX_DATA_SEARCH:
1138 print_indent();
1139 printf("search { ");
1140 for(cur = clist_begin(mb_data->mbd_data.mbd_search) ;
1141 cur != NULL ; cur = clist_next(cur)) {
1142 uint32_t * id;
1143
1144 id = clist_content(cur);
1145 printf("%i ", * id);
1146 }
1147 printf(" }\n");
1148 break;
1149
1150 case MAILIMAP_MAILBOX_DATA_STATUS:
1151 print_indent();
1152 printf("status {\n");
1153 indent();
1154 mailimap_mailbox_data_status_print(mb_data->mbd_data.mbd_status);
1155 unindent();
1156 print_indent();
1157 printf("}\n");
1158 break;
1159
1160 case MAILIMAP_MAILBOX_DATA_EXISTS:
1161 print_indent();
1162 printf("exists { %i }\n", mb_data->mbd_data.mbd_exists);
1163 break;
1164
1165 case MAILIMAP_MAILBOX_DATA_RECENT:
1166 print_indent();
1167 printf("recent { %i }\n", mb_data->mbd_data.mbd_recent);
1168 break;
1169 }
1170
1171 unindent();
1172 print_indent();
1173 printf("}\n");
1174}
1175
1176static void
1177mailimap_resp_text_code_print(struct mailimap_resp_text_code * text_code);
1178
1179static void mailimap_resp_text_print(struct mailimap_resp_text * resp_text);
1180
1181static void mailimap_resp_cond_bye_print(struct mailimap_resp_cond_bye *
1182 resp_cond_bye)
1183{
1184 print_indent();
1185 printf("resp-cond-bye {\n");
1186 indent();
1187 mailimap_resp_text_print(resp_cond_bye->rsp_text);
1188 unindent();
1189 print_indent();
1190 printf("}\n");
1191}
1192
1193static void mailimap_resp_cond_state_print(struct mailimap_resp_cond_state *
1194 resp_cond_state)
1195{
1196 print_indent();
1197 printf("resp-cond-state {\n");
1198 indent();
1199
1200 switch(resp_cond_state->rsp_type) {
1201 case MAILIMAP_RESP_COND_STATE_OK:
1202 print_indent();
1203 printf("OK\n");
1204 break;
1205 case MAILIMAP_RESP_COND_STATE_NO:
1206 print_indent();
1207 printf("NO\n");
1208 break;
1209 case MAILIMAP_RESP_COND_STATE_BAD:
1210 print_indent();
1211 printf("BAD\n");
1212 break;
1213 }
1214
1215 mailimap_resp_text_print(resp_cond_state->rsp_text);
1216
1217 unindent();
1218 print_indent();
1219 printf("}\n");
1220}
1221
1222static void mailimap_capability_data_print(struct mailimap_capability_data *
1223 cap_data);
1224
1225static void mailimap_response_data_print(struct mailimap_response_data *
1226 resp_data)
1227{
1228 print_indent();
1229 printf("response-data {\n");
1230 indent();
1231
1232 switch (resp_data->rsp_type) {
1233 case MAILIMAP_RESP_DATA_TYPE_COND_STATE:
1234 mailimap_resp_cond_state_print(resp_data->rsp_data.rsp_cond_state);
1235 break;
1236 case MAILIMAP_RESP_DATA_TYPE_COND_BYE:
1237 mailimap_resp_cond_bye_print(resp_data->rsp_data.rsp_bye);
1238 break;
1239 case MAILIMAP_RESP_DATA_TYPE_MAILBOX_DATA:
1240 mailimap_mailbox_data_print(resp_data->rsp_data.rsp_mailbox_data);
1241 break;
1242 case MAILIMAP_RESP_DATA_TYPE_MESSAGE_DATA:
1243 mailimap_message_data_print(resp_data->rsp_data.rsp_message_data);
1244 break;
1245 case MAILIMAP_RESP_DATA_TYPE_CAPABILITY_DATA:
1246 mailimap_capability_data_print(resp_data->rsp_data.rsp_capability_data);
1247 break;
1248 }
1249
1250 unindent();
1251 print_indent();
1252 printf("}\n");
1253}
1254
1255static void mailimap_flag_print(struct mailimap_flag * flag)
1256{
1257 printf("flag { ");
1258
1259 switch (flag->fl_type) {
1260 case MAILIMAP_FLAG_ANSWERED:
1261 printf("answered");
1262 break;
1263
1264 case MAILIMAP_FLAG_FLAGGED:
1265 printf("flagged");
1266 break;
1267
1268 case MAILIMAP_FLAG_DELETED:
1269 printf("deleted");
1270 break;
1271
1272 case MAILIMAP_FLAG_SEEN:
1273 printf("seen");
1274 break;
1275
1276 case MAILIMAP_FLAG_DRAFT:
1277 printf("flag draft");
1278 break;
1279
1280 case MAILIMAP_FLAG_KEYWORD:
1281 printf("keyword { %s }", flag->fl_data.fl_keyword);
1282 break;
1283
1284 case MAILIMAP_FLAG_EXTENSION:
1285 printf("extention { %s }", flag->fl_data.fl_extension);
1286 break;
1287 }
1288
1289 printf(" }");
1290}
1291
1292static void mailimap_flag_perm_print(struct mailimap_flag_perm * flag_perm)
1293{
1294 print_indent();
1295 printf("flag-perm { ");
1296
1297 switch (flag_perm->fl_type) {
1298 case MAILIMAP_FLAG_PERM_FLAG:
1299 mailimap_flag_print(flag_perm->fl_flag);
1300 break;
1301
1302 case MAILIMAP_FLAG_PERM_ALL:
1303 printf("all");
1304 break;
1305 }
1306
1307 printf(" }\n");
1308}
1309
1310static void mailimap_capability_print(struct mailimap_capability * cap)
1311{
1312 print_indent();
1313 printf("capability { ");
1314
1315 switch (cap->cap_type) {
1316 case MAILIMAP_CAPABILITY_AUTH_TYPE:
1317 printf("auth { %s }", cap->cap_data.cap_auth_type);
1318 break;
1319 case MAILIMAP_CAPABILITY_NAME:
1320 printf("atom { %s }", cap->cap_data.cap_name);
1321 break;
1322 }
1323
1324 printf(" }\n");
1325}
1326
1327static void mailimap_capability_data_print(struct mailimap_capability_data *
1328 cap_data)
1329{
1330 clistiter * cur;
1331
1332 print_indent();
1333 printf("capability-data {\n");
1334 indent();
1335
1336 for(cur = clist_begin(cap_data->cap_list) ; cur != NULL ;
1337 cur = clist_next(cur)) {
1338 struct mailimap_capability * cap;
1339
1340 cap = clist_content(cur);
1341
1342 mailimap_capability_print(cap);
1343 }
1344
1345 unindent();
1346 print_indent();
1347 printf("}\n");
1348}
1349
1350static void
1351mailimap_resp_text_code_print(struct mailimap_resp_text_code * text_code)
1352{
1353 clistiter * cur;
1354
1355 print_indent();
1356 printf("resp-text-code {\n");
1357 indent();
1358
1359 switch (text_code->rc_type) {
1360 case MAILIMAP_RESP_TEXT_CODE_BADCHARSET:
1361 print_indent();
1362 printf("badcharset { ");
1363 for(cur = clist_begin(text_code->rc_data.rc_badcharset) ; cur != NULL ;
1364 cur = clist_next(cur))
1365 printf("%s ", (char *) clist_content(cur));
1366 printf("}\n");
1367 break;
1368
1369 case MAILIMAP_RESP_TEXT_CODE_CAPABILITY_DATA:
1370 print_indent();
1371 printf("capability {\n");
1372 indent();
1373 mailimap_capability_data_print(text_code->rc_data.rc_cap_data);
1374 unindent();
1375 print_indent();
1376 printf("}\n");
1377 break;
1378
1379 case MAILIMAP_RESP_TEXT_CODE_PERMANENTFLAGS:
1380 print_indent();
1381 printf("permanent-flags {\n");
1382 indent();
1383 cur = clist_begin(text_code->rc_data.rc_perm_flags);
1384 while (cur != NULL) {
1385 mailimap_flag_perm_print(clist_content(cur));
1386 cur = clist_next(cur);
1387 }
1388 unindent();
1389 print_indent();
1390 printf("}\n");
1391 break;
1392
1393 case MAILIMAP_RESP_TEXT_CODE_READ_ONLY:
1394 print_indent();
1395 printf("readonly\n");
1396 break;
1397
1398 case MAILIMAP_RESP_TEXT_CODE_READ_WRITE:
1399 print_indent();
1400 printf("readwrite\n");
1401 break;
1402
1403 case MAILIMAP_RESP_TEXT_CODE_TRY_CREATE:
1404 print_indent();
1405 printf("trycreate\n");
1406 break;
1407
1408 case MAILIMAP_RESP_TEXT_CODE_UIDNEXT:
1409 print_indent();
1410 printf("uidnext { %i }\n", text_code->rc_data.rc_uidnext);
1411 break;
1412
1413 case MAILIMAP_RESP_TEXT_CODE_UIDVALIDITY:
1414 print_indent();
1415 printf("uidvalidity { %i }\n", text_code->rc_data.rc_uidvalidity);
1416 break;
1417
1418 case MAILIMAP_RESP_TEXT_CODE_UNSEEN:
1419 print_indent();
1420 printf("unseen { %i }\n", text_code->rc_data.rc_first_unseen);
1421 break;
1422
1423 case MAILIMAP_RESP_TEXT_CODE_OTHER:
1424 print_indent();
1425 printf("other { %s = %s }\n",
1426 text_code->rc_data.rc_atom.atom_name,
1427 text_code->rc_data.rc_atom.atom_value);
1428 break;
1429 }
1430
1431 unindent();
1432 print_indent();
1433 printf("}\n");
1434}
1435
1436static void mailimap_resp_text_print(struct mailimap_resp_text * resp_text)
1437{
1438 print_indent();
1439 printf("resp-text {\n");
1440 indent();
1441
1442 if (resp_text->rsp_code)
1443 mailimap_resp_text_code_print(resp_text->rsp_code);
1444 print_indent();
1445 printf("text { %s }\n", resp_text->rsp_text);
1446
1447 unindent();
1448 print_indent();
1449 printf("}\n");
1450}
1451
1452static void mailimap_continue_req_print(struct mailimap_continue_req *
1453 cont_req)
1454{
1455 print_indent();
1456 printf("continue-req {\n");
1457 indent();
1458
1459 switch (cont_req->cr_type) {
1460 case MAILIMAP_CONTINUE_REQ_TEXT:
1461 print_indent();
1462 printf("resp-text {\n");
1463 indent();
1464 mailimap_resp_text_print(cont_req->cr_data.cr_text);
1465 unindent();
1466 print_indent();
1467 printf("}\n");
1468 break;
1469 case MAILIMAP_CONTINUE_REQ_BASE64:
1470 printf("base64 { %s }\n", cont_req->cr_data.cr_base64);
1471 break;
1472 }
1473
1474 unindent();
1475 print_indent();
1476 printf("}\n");
1477}
1478
1479static void mailimap_cont_req_or_resp_data_print(struct mailimap_cont_req_or_resp_data * cont_req_or_resp_data)
1480{
1481 print_indent();
1482 printf("cont-req-or-resp-data {\n");
1483 indent();
1484
1485 switch (cont_req_or_resp_data->rsp_type) {
1486 case MAILIMAP_RESP_CONT_REQ:
1487 mailimap_continue_req_print(cont_req_or_resp_data->rsp_data.rsp_cont_req);
1488 break;
1489 case MAILIMAP_RESP_RESP_DATA:
1490 mailimap_response_data_print(cont_req_or_resp_data->rsp_data.rsp_resp_data);
1491 break;
1492 }
1493
1494 unindent();
1495 print_indent();
1496 printf("}\n");
1497}
1498
1499static void mailimap_response_tagged_print(struct mailimap_response_tagged *
1500 tagged)
1501{
1502 print_indent();
1503 printf("response-tagged {\n");
1504 indent();
1505
1506 print_indent();
1507 printf("tag { %s }\n", tagged->rsp_tag);
1508 mailimap_resp_cond_state_print(tagged->rsp_cond_state);
1509
1510 unindent();
1511 print_indent();
1512 printf("}\n");
1513}
1514
1515static void mailimap_response_fatal_print(struct mailimap_response_fatal *
1516 fatal)
1517{
1518 print_indent();
1519 printf("response-fatal {\n");
1520 indent();
1521
1522 mailimap_resp_cond_bye_print(fatal->rsp_bye);
1523
1524 unindent();
1525 print_indent();
1526 printf("}\n");
1527}
1528
1529static void mailimap_response_done_print(struct mailimap_response_done *
1530 resp_done)
1531{
1532 print_indent();
1533 printf("response-done {\n");
1534 indent();
1535
1536 switch (resp_done->rsp_type) {
1537 case MAILIMAP_RESP_DONE_TYPE_TAGGED:
1538 mailimap_response_tagged_print(resp_done->rsp_data.rsp_tagged);
1539 break;
1540 case MAILIMAP_RESP_DONE_TYPE_FATAL:
1541 mailimap_response_fatal_print(resp_done->rsp_data.rsp_fatal);
1542 break;
1543 }
1544
1545 unindent();
1546 print_indent();
1547 printf("}\n");
1548}
1549
1550void mailimap_response_print(struct mailimap_response * resp)
1551{
1552 clistiter * cur;
1553
1554 print_indent();
1555 printf("response {\n");
1556 indent();
1557
1558 for(cur = clist_begin(resp->rsp_cont_req_or_resp_data_list) ; cur != NULL ;
1559 cur = clist_next(cur)) {
1560 struct mailimap_cont_req_or_resp_data * resp;
1561
1562 resp = clist_content(cur);
1563
1564 mailimap_cont_req_or_resp_data_print(resp);
1565 }
1566
1567 mailimap_response_done_print(resp->rsp_resp_done);
1568
1569 unindent();
1570 print_indent();
1571 printf("}\n");
1572}
1573
1574static void mailimap_resp_cond_auth_print(struct mailimap_resp_cond_auth *
1575 cond_auth)
1576{
1577 print_indent();
1578 printf("resp-cond-auth {\n");
1579 indent();
1580
1581 switch (cond_auth->rsp_type) {
1582 case MAILIMAP_RESP_COND_AUTH_OK:
1583 print_indent();
1584 printf("OK\n");
1585 case MAILIMAP_RESP_COND_AUTH_PREAUTH:
1586 print_indent();
1587 printf("PREAUTH\n");
1588 }
1589 mailimap_resp_text_print(cond_auth->rsp_text);
1590
1591 unindent();
1592 print_indent();
1593 printf("}\n");
1594}
1595
1596void mailimap_greeting_print(struct mailimap_greeting * greeting)
1597{
1598 print_indent();
1599 printf("greeting {\n");
1600 indent();
1601
1602 switch(greeting->gr_type) {
1603 case MAILIMAP_GREETING_RESP_COND_AUTH:
1604 mailimap_resp_cond_auth_print(greeting->gr_data.gr_auth);
1605 break;
1606 case MAILIMAP_GREETING_RESP_COND_BYE:
1607 mailimap_resp_cond_bye_print(greeting->gr_data.gr_bye);
1608 break;
1609 }
1610
1611 unindent();
1612 print_indent();
1613 printf("}\n");
1614}
1615#endif
diff --git a/kmicromail/libetpan/imap/mailimap_print.h b/kmicromail/libetpan/imap/mailimap_print.h
new file mode 100644
index 0000000..24016fa
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_print.h
@@ -0,0 +1,54 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_PRINT_H
37
38#define MAILIMAP_PRINT_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mailimap_types.h"
45
46void mailimap_response_print(struct mailimap_response * resp);
47
48void mailimap_greeting_print(struct mailimap_greeting * greeting);
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/kmicromail/libetpan/imap/mailimap_sender.c b/kmicromail/libetpan/imap/mailimap_sender.c
new file mode 100644
index 0000000..ac4bfe8
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_sender.c
@@ -0,0 +1,2743 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailstream.h"
37#include "mailimap_keywords.h"
38#include "mailimap_sender.h"
39#include "clist.h"
40#include "mail.h"
41#include <string.h>
42
43#include <stdio.h>
44#include <ctype.h>
45
46/*
47 TODO :
48 implement progression for literal
49*/
50
51/* ************************************************************************* */
52/* ************************************************************************* */
53/* ************************************************************************* */
54/* ************************************************************************* */
55/* ************************************************************************* */
56/* ************************************************************************* */
57
58
59
60
61static int mailimap_atom_send(mailstream * fd, const char * atom);
62
63static int mailimap_auth_type_send(mailstream * fd, const char * auth_type);
64
65static int mailimap_base64_send(mailstream * fd, const char * base64);
66
67
68static int mailimap_date_send(mailstream * fd,
69 struct mailimap_date * date);
70
71static int mailimap_date_day_send(mailstream * fd, int day);
72
73static int mailimap_date_month_send(mailstream * fd, int month);
74
75
76/*
77static gboolean mailimap_date_text_send(mailstream * fd,
78 struct mailimap_date_text * date_text);
79*/
80
81
82static int mailimap_date_year_send(mailstream *fd, int year);
83
84static int
85mailimap_date_time_send(mailstream * fd,
86 struct mailimap_date_time * date_time);
87
88static int mailimap_digit_send(mailstream * fd, int digit);
89
90
91
92static int
93mailimap_fetch_type_send(mailstream * fd,
94 struct mailimap_fetch_type * fetch_type);
95
96
97static int mailimap_fetch_att_send(mailstream * fd,
98 struct mailimap_fetch_att * fetch_att);
99
100
101static int mailimap_flag_send(mailstream * fd,
102 struct mailimap_flag * flag);
103
104
105static int mailimap_flag_extension_send(mailstream * fd,
106 const char * flag_extension);
107
108
109static int mailimap_flag_keyword_send(mailstream * fd,
110 const char * flag_keyword);
111
112
113static int mailimap_flag_list_send(mailstream * fd,
114 struct mailimap_flag_list * flag_list);
115
116
117
118static int mailimap_header_fld_name_send(mailstream * fd, const char * header);
119
120
121static int
122mailimap_header_list_send(mailstream * fd,
123 struct mailimap_header_list * header_list);
124
125static int
126mailimap_list_mailbox_send(mailstream * fd, const char * pattern);
127
128
129static int mailimap_mailbox_send(mailstream * fd, const char * mb);
130
131static int mailimap_number_send(mailstream * fd, uint32_t number);
132
133static int mailimap_password_send(mailstream * fd, const char * pass);
134
135static int mailimap_quoted_char_send(mailstream * fd, char ch);
136
137static int mailimap_quoted_send(mailstream * fd, const char * quoted);
138
139
140static int mailimap_search_key_send(mailstream * fd,
141 struct mailimap_search_key * key);
142
143static int
144mailimap_section_send(mailstream * fd,
145 struct mailimap_section * section);
146
147static int
148mailimap_section_msgtext_send(mailstream * fd,
149 struct mailimap_section_msgtext *
150 section_msgtext);
151
152
153static int
154mailimap_section_part_send(mailstream * fd,
155 struct mailimap_section_part * section);
156
157
158static int
159mailimap_section_spec_send(mailstream * fd,
160 struct mailimap_section_spec * section_spec);
161
162
163static int
164mailimap_section_text_send(mailstream * fd,
165 struct mailimap_section_text * section_text);
166
167
168static int
169mailimap_sequence_num_send(mailstream * fd, uint32_t sequence_num);
170
171
172static int mailimap_set_item_send(mailstream * fd,
173 struct mailimap_set_item * item);
174
175
176static int mailimap_set_send(mailstream * fd,
177 struct mailimap_set * set);
178
179
180
181static int mailimap_status_att_send(mailstream * fd, int * status_att);
182
183
184
185static int
186mailimap_store_att_flags_send(mailstream * fd,
187 struct mailimap_store_att_flags * store_flags);
188
189
190static int mailimap_userid_send(mailstream * fd, const char * user);
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205/* ************************************************************************* */
206/* ************************************************************************* */
207/* ************************************************************************* */
208/* ************************************************************************* */
209/* ************************************************************************* */
210/* ************************************************************************* */
211
212
213
214
215
216static int mailimap_sized_token_send(mailstream * fd, const char * atom,
217 size_t len)
218{
219 if (mailstream_write(fd, atom, len) == -1)
220 return MAILIMAP_ERROR_STREAM;
221
222 return MAILIMAP_NO_ERROR;
223}
224
225static int mailimap_token_send(mailstream * fd, const char * atom)
226{
227 if (mailstream_write(fd, atom, strlen(atom)) == -1)
228 return MAILIMAP_ERROR_STREAM;
229
230 return MAILIMAP_NO_ERROR;
231}
232
233static int mailimap_char_send(mailstream * fd, char ch)
234{
235 if (mailstream_write(fd, &ch, 1) == -1)
236 return MAILIMAP_ERROR_STREAM;
237
238 return MAILIMAP_NO_ERROR;
239}
240
241typedef int mailimap_struct_sender(mailstream * fd, void * data);
242
243static int
244mailimap_struct_list_send(mailstream * fd, clist * list,
245 char symbol,
246 mailimap_struct_sender * sender)
247{
248 clistiter * cur;
249 void * elt;
250 int r;
251
252 cur = clist_begin(list);
253
254 if (cur == NULL)
255 return MAILIMAP_NO_ERROR;
256
257 elt = clist_content(cur);
258 r = (* sender)(fd, elt);
259 if (r != MAILIMAP_NO_ERROR)
260 return r;
261 cur = clist_next(cur);
262
263 while (cur != NULL) {
264 r = mailimap_char_send(fd, symbol);
265 if (r != MAILIMAP_NO_ERROR)
266 return r;
267 elt = clist_content(cur);
268 r = (* sender)(fd, elt);
269 if (r != MAILIMAP_NO_ERROR)
270 return r;
271 cur = clist_next(cur);
272 }
273
274 return MAILIMAP_NO_ERROR;
275}
276
277
278static int
279mailimap_struct_spaced_list_send(mailstream * fd, clist * list,
280 mailimap_struct_sender * sender)
281{
282 return mailimap_struct_list_send(fd, list, ' ', sender);
283}
284
285int mailimap_space_send(mailstream * fd)
286{
287 return mailimap_char_send(fd, ' ');
288}
289
290int mailimap_crlf_send(mailstream * fd)
291{
292 int r;
293
294 r = mailimap_char_send(fd, '\r');
295 if (r != MAILIMAP_NO_ERROR)
296 return r;
297 r = mailimap_char_send(fd, '\n');
298 if (r != MAILIMAP_NO_ERROR)
299 return r;
300
301 return MAILIMAP_NO_ERROR;
302}
303
304static int mailimap_oparenth_send(mailstream * fd)
305{
306 return mailimap_char_send(fd, '(');
307}
308
309static int mailimap_cparenth_send(mailstream * fd)
310{
311 return mailimap_char_send(fd, ')');
312}
313
314static int mailimap_dquote_send(mailstream * fd)
315{
316 return mailimap_char_send(fd, '"');
317}
318
319/*
320 address = "(" addr-name SP addr-adl SP addr-mailbox SP
321 addr-host ")"
322
323 addr-adl = nstring
324 ; Holds route from [RFC-822] route-addr if
325 ; non-NIL
326
327 addr-host = nstring
328 ; NIL indicates [RFC-822] group syntax.
329 ; Otherwise, holds [RFC-822] domain name
330
331 addr-mailbox = nstring
332 ; NIL indicates end of [RFC-822] group; if
333 ; non-NIL and addr-host is NIL, holds
334 ; [RFC-822] group name.
335 ; Otherwise, holds [RFC-822] local-part
336 ; after removing [RFC-822] quoting
337
338 addr-name = nstring
339 ; If non-NIL, holds phrase from [RFC-822]
340 ; mailbox after removing [RFC-822] quoting
341*/
342
343/*
344=> append = "APPEND" SP mailbox [SP flag-list] [SP date-time] SP
345 literal
346*/
347
348int mailimap_append_send(mailstream * fd,
349 const char * mailbox,
350 struct mailimap_flag_list * flag_list,
351 struct mailimap_date_time * date_time,
352 size_t literal_size)
353{
354 int r;
355
356 r = mailimap_token_send(fd, "APPEND");
357 if (r != MAILIMAP_NO_ERROR)
358 return r;
359 r = mailimap_space_send(fd);
360 if (r != MAILIMAP_NO_ERROR)
361 return r;
362 r = mailimap_mailbox_send(fd, mailbox);
363 if (r != MAILIMAP_NO_ERROR)
364 return r;
365 if (flag_list != NULL) {
366 r = mailimap_space_send(fd);
367 if (r != MAILIMAP_NO_ERROR)
368 return r;
369 r = mailimap_flag_list_send(fd, flag_list);
370 if (r != MAILIMAP_NO_ERROR)
371 return r;
372 }
373 if (date_time != NULL) {
374 r = mailimap_space_send(fd);
375 if (r != MAILIMAP_NO_ERROR)
376 return r;
377 r = mailimap_date_time_send(fd, date_time);
378 if (r != MAILIMAP_NO_ERROR)
379 return r;
380 }
381
382 r = mailimap_space_send(fd);
383 if (r != MAILIMAP_NO_ERROR)
384 return r;
385 r = mailimap_literal_count_send(fd, literal_size);
386 if (r != MAILIMAP_NO_ERROR)
387 return r;
388
389 return MAILIMAP_NO_ERROR;
390}
391
392/*
393 astring = 1*ASTRING-CHAR / string
394
395=> ASTRING-CHAR = ATOM-CHAR / resp-specials
396*/
397
398static int is_atom(const char * str)
399{
400 if (* str == '\0')
401 return 0;
402
403 while (* str != '\0') {
404 unsigned char uch = (unsigned char) * str;
405
406 if (!isalnum(uch))
407 return 0;
408
409 str ++;
410 }
411
412 return 1;
413}
414
415static int mailimap_astring_send(mailstream * fd, const char * astring)
416{
417 /*
418 workaround for buggy Courier-IMAP that does not accept
419 quoted-strings for fields name but prefer atoms.
420 */
421 if (is_atom(astring))
422 return mailimap_atom_send(fd, astring);
423 else
424 return mailimap_quoted_send(fd, astring);
425}
426
427/*
428=> atom = 1*ATOM-CHAR
429*/
430
431static int mailimap_atom_send(mailstream * fd, const char * atom)
432{
433 return mailimap_token_send(fd, atom);
434}
435
436/*
437=> ATOM-CHAR = <any CHAR except atom-specials>
438*/
439
440/*
441=> atom-specials = "(" / ")" / "{" / SP / CTL / list-wildcards /
442 quoted-specials / resp-specials
443*/
444
445/*
446=> authenticate = "AUTHENTICATE" SP auth-type *(CRLF base64)
447*/
448
449int mailimap_authenticate_send(mailstream * fd,
450 const char * auth_type)
451{
452 int r;
453
454 r = mailimap_token_send(fd, "AUTHENTICATE");
455 if (r != MAILIMAP_NO_ERROR)
456 return r;
457 r = mailimap_space_send(fd);
458 if (r != MAILIMAP_NO_ERROR)
459 return r;
460 r = mailimap_auth_type_send(fd, auth_type);
461 if (r != MAILIMAP_NO_ERROR)
462 return r;
463
464 return MAILIMAP_NO_ERROR;
465}
466
467int mailimap_authenticate_resp_send(mailstream * fd,
468 const char * base64)
469{
470 int r;
471
472 r = mailimap_base64_send(fd, base64);
473 if (r != MAILIMAP_NO_ERROR)
474 return r;
475
476 return MAILIMAP_NO_ERROR;
477}
478
479/*
480=> auth-type = atom
481 ; Defined by [SASL]
482*/
483
484static int mailimap_auth_type_send(mailstream * fd, const char * auth_type)
485{
486 return mailimap_atom_send(fd, auth_type);
487}
488
489
490/*
491=> base64 = *(4base64-char) [base64-terminal]
492*/
493
494static int mailimap_base64_send(mailstream * fd, const char * base64)
495{
496 return mailimap_token_send(fd, base64);
497}
498
499/*
500=> base64-char = ALPHA / DIGIT / "+" / "/"
501 ; Case-sensitive
502
503 base64-terminal = (2base64-char "==") / (3base64-char "=")
504
505 body = "(" (body-type-1part / body-type-mpart) ")"
506
507 body-extension = nstring / number /
508 "(" body-extension *(SP body-extension) ")"
509 ; Future expansion. Client implementations
510 ; MUST accept body-extension fields. Server
511 ; implementations MUST NOT generate
512 ; body-extension fields except as defined by
513 ; future standard or standards-track
514 ; revisions of this specification.
515
516 body-ext-1part = body-fld-md5 [SP body-fld-dsp [SP body-fld-lang
517 *(SP body-extension)]]
518 ; MUST NOT be returned on non-extensible
519 ; "BODY" fetch
520
521 body-ext-mpart = body-fld-param [SP body-fld-dsp [SP body-fld-lang
522 *(SP body-extension)]]
523 ; MUST NOT be returned on non-extensible
524 ; "BODY" fetch
525
526 body-fields = body-fld-param SP body-fld-id SP body-fld-desc SP
527 body-fld-enc SP body-fld-octets
528
529 body-fld-desc = nstring
530
531 body-fld-dsp = "(" string SP body-fld-param ")" / nil
532
533 body-fld-enc = (DQUOTE ("7BIT" / "8BIT" / "BINARY" / "BASE64"/
534 "QUOTED-PRINTABLE") DQUOTE) / string
535
536 body-fld-id = nstring
537
538 body-fld-lang = nstring / "(" string *(SP string) ")"
539
540 body-fld-lines = number
541
542 body-fld-md5 = nstring
543
544 body-fld-octets = number
545
546 body-fld-param = "(" string SP string *(SP string SP string) ")" / nil
547
548 body-type-1part = (body-type-basic / body-type-msg / body-type-text)
549 [SP body-ext-1part]
550
551 body-type-basic = media-basic SP body-fields
552 ; MESSAGE subtype MUST NOT be "RFC822"
553
554 body-type-mpart = 1*body SP media-subtype
555 [SP body-ext-mpart]
556
557 body-type-msg = media-message SP body-fields SP envelope
558 SP body SP body-fld-lines
559
560 body-type-text = media-text SP body-fields SP body-fld-lines
561
562 capability = ("AUTH=" auth-type) / atom
563 ; New capabilities MUST begin with "X" or be
564 ; registered with IANA as standard or
565 ; standards-track
566
567 capability-data = "CAPABILITY" *(SP capability) SP "IMAP4rev1"
568 *(SP capability)
569 ; IMAP4rev1 servers which offer RFC 1730
570 ; compatibility MUST list "IMAP4" as the first
571 ; capability.
572
573 CHAR8 = %x01-ff
574 ; any OCTET except NUL, %x00
575*/
576
577/*
578=> command = tag SP (command-any / command-auth / command-nonauth /
579 command-select) CRLF
580 ; Modal based on state
581*/
582
583/*
584=> command-any = "CAPABILITY" / "LOGOUT" / "NOOP" / x-command
585 ; Valid in all states
586*/
587
588int mailimap_capability_send(mailstream * fd)
589{
590 int r;
591
592 r = mailimap_token_send(fd, "CAPABILITY");
593 if (r != MAILIMAP_NO_ERROR)
594 return r;
595
596 return MAILIMAP_NO_ERROR;
597}
598
599int mailimap_logout_send(mailstream * fd)
600{
601 int r;
602
603 r = mailimap_token_send(fd, "LOGOUT");
604 if (r != MAILIMAP_NO_ERROR)
605 return r;
606
607 return MAILIMAP_NO_ERROR;
608}
609
610int mailimap_noop_send(mailstream * fd)
611{
612 int r;
613
614 r = mailimap_token_send(fd, "NOOP");
615 if (r != MAILIMAP_NO_ERROR)
616 return r;
617
618 return MAILIMAP_NO_ERROR;
619}
620
621/*
622=> command-auth = append / create / delete / examine / list / lsub /
623 rename / select / status / subscribe / unsubscribe
624 ; Valid only in Authenticated or Selected state
625*/
626
627/*
628=> command-nonauth = login / authenticate
629 ; Valid only when in Not Authenticated state
630*/
631
632/*
633=> command-select = "CHECK" / "CLOSE" / "EXPUNGE" / copy / fetch / store /
634 uid / search
635 ; Valid only when in Selected state
636*/
637
638int mailimap_check_send(mailstream * fd)
639{
640 int r;
641
642 r = mailimap_token_send(fd, "CHECK");
643 if (r != MAILIMAP_NO_ERROR)
644 return r;
645
646 return MAILIMAP_NO_ERROR;
647}
648
649int mailimap_close_send(mailstream * fd)
650{
651 int r;
652
653 r = mailimap_token_send(fd, "CLOSE");
654 if (r != MAILIMAP_NO_ERROR)
655 return r;
656
657 return MAILIMAP_NO_ERROR;
658}
659
660int mailimap_expunge_send(mailstream * fd)
661{
662 int r;
663
664 r = mailimap_token_send(fd, "EXPUNGE");
665 if (r != MAILIMAP_NO_ERROR)
666 return r;
667
668 return MAILIMAP_NO_ERROR;
669}
670
671/*
672 continue-req = "+" SP (resp-text / base64) CRLF
673*/
674
675/*
676=> copy = "COPY" SP set SP mailbox
677*/
678
679int mailimap_copy_send(mailstream * fd,
680 struct mailimap_set * set,
681 const char * mb)
682{
683 int r;
684
685 r = mailimap_token_send(fd, "COPY");
686 if (r != MAILIMAP_NO_ERROR)
687 return r;
688
689 r = mailimap_space_send(fd);
690 if (r != MAILIMAP_NO_ERROR)
691 return r;
692
693 r = mailimap_set_send(fd, set);
694 if (r != MAILIMAP_NO_ERROR)
695 return r;
696
697 r = mailimap_space_send(fd);
698 if (r != MAILIMAP_NO_ERROR)
699 return r;
700
701 r = mailimap_mailbox_send(fd, mb);
702 if (r != MAILIMAP_NO_ERROR)
703 return r;
704
705 return MAILIMAP_NO_ERROR;
706}
707
708int mailimap_uid_copy_send(mailstream * fd,
709 struct mailimap_set * set,
710 const char * mb)
711{
712 int r;
713
714 r = mailimap_token_send(fd, "UID");
715 if (r != MAILIMAP_NO_ERROR)
716 return r;
717
718 r = mailimap_space_send(fd);
719 if (r != MAILIMAP_NO_ERROR)
720 return r;
721
722 return mailimap_copy_send(fd, set, mb);
723}
724
725/*
726=> create = "CREATE" SP mailbox
727 ; Use of INBOX gives a NO error
728*/
729
730int mailimap_create_send(mailstream * fd,
731 const char * mb)
732{
733 int r;
734
735 r = mailimap_token_send(fd, "CREATE");
736 if (r != MAILIMAP_NO_ERROR)
737 return r;
738
739 r = mailimap_space_send(fd);
740 if (r != MAILIMAP_NO_ERROR)
741 return r;
742
743 r = mailimap_mailbox_send(fd, mb);
744 if (r != MAILIMAP_NO_ERROR)
745 return r;
746
747 return MAILIMAP_NO_ERROR;
748}
749
750/*
751=> date = date-text / DQUOTE date-text DQUOTE
752*/
753
754static int mailimap_date_send(mailstream * fd,
755 struct mailimap_date * date)
756{
757 int r;
758
759 r = mailimap_date_day_send(fd, date->dt_day);
760 if (r != MAILIMAP_NO_ERROR)
761 return r;
762
763 r = mailimap_char_send(fd, '-');
764 if (r != MAILIMAP_NO_ERROR)
765 return r;
766
767 r = mailimap_date_month_send(fd, date->dt_month);
768 if (r != MAILIMAP_NO_ERROR)
769 return r;
770
771 r = mailimap_char_send(fd, '-');
772 if (r != MAILIMAP_NO_ERROR)
773 return r;
774
775 r = mailimap_date_year_send(fd, date->dt_year);
776 if (r != MAILIMAP_NO_ERROR)
777 return r;
778
779 return MAILIMAP_NO_ERROR;
780}
781
782/*
783=> date-day = 1*2DIGIT
784 ; Day of month
785*/
786
787static int mailimap_date_day_send(mailstream * fd, int day)
788{
789 return mailimap_number_send(fd, day);
790}
791
792/*
793=> date-day-fixed = (SP DIGIT) / 2DIGIT
794 ; Fixed-format version of date-day
795*/
796
797static int mailimap_date_day_fixed_send(mailstream * fd, int day)
798{
799 int r;
800
801 if (day < 10) {
802 r = mailimap_space_send(fd);
803 if (r != MAILIMAP_NO_ERROR)
804 return r;
805
806 r = mailimap_number_send(fd, day);
807 if (r != MAILIMAP_NO_ERROR)
808 return r;
809
810 return MAILIMAP_NO_ERROR;
811 }
812 else
813 return mailimap_number_send(fd, day);
814}
815
816/*
817=> date-month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" /
818 "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
819*/
820
821static int mailimap_date_month_send(mailstream * fd, int month)
822{
823 const char * name;
824 int r;
825
826 name = mailimap_month_get_token_str(month);
827
828 if (name == NULL)
829 return MAILIMAP_ERROR_INVAL;
830
831 r = mailimap_token_send(fd, name);
832 if (r != MAILIMAP_NO_ERROR)
833 return r;
834
835 return MAILIMAP_NO_ERROR;
836}
837
838/*
839=> date-text = date-day "-" date-month "-" date-year
840*/
841
842/*
843static gboolean mailimap_date_text_send(mailstream * fd,
844 struct mailimap_date_text * date_text)
845{
846 if (!mailimap_date_day_send(fd, date_text->day))
847 return FALSE;
848 if (!mailimap_char_send(fd, '-'))
849 return FALSE;
850 if (!mailimap_date_month_send(fd, date_text->month))
851 return FALSE;
852 if (!mailimap_char_send(fd, '-'))
853 return FALSE;
854 if (!mailimap_date_year_send(fd, date_text->year))
855 return FALSE;
856
857 return TRUE;
858}
859*/
860
861/*
862=> date-year = 4DIGIT
863*/
864
865static int mailimap_fixed_digit_send(mailstream * fd,
866 int num, int count)
867{
868 int r;
869
870 r = mailimap_fixed_digit_send(fd, num / 10, count);
871 if (r != MAILIMAP_NO_ERROR)
872 return r;
873
874 r = mailimap_digit_send(fd, num % 10);
875 if (r != MAILIMAP_NO_ERROR)
876 return r;
877
878 return MAILIMAP_NO_ERROR;
879}
880
881static int mailimap_date_year_send(mailstream *fd, int year)
882{
883 int r;
884
885 r = mailimap_fixed_digit_send(fd, year, 4);
886 if (r != MAILIMAP_NO_ERROR)
887 return r;
888
889 return MAILIMAP_NO_ERROR;
890}
891
892/*
893=> date-time = DQUOTE date-day-fixed "-" date-month "-" date-year
894 SP time SP zone DQUOTE
895*/
896
897static int
898mailimap_date_time_send(mailstream * fd,
899 struct mailimap_date_time * date_time)
900{
901 int r;
902
903 r = mailimap_date_day_fixed_send(fd, date_time->dt_day);
904 if (r != MAILIMAP_NO_ERROR)
905 return r;
906
907 r = mailimap_char_send(fd, '-');
908 if (r != MAILIMAP_NO_ERROR)
909 return r;
910
911 r = mailimap_date_month_send(fd, date_time->dt_month);
912 if (r != MAILIMAP_NO_ERROR)
913 return r;
914
915 r = mailimap_char_send(fd, '-');
916 if (r != MAILIMAP_NO_ERROR)
917 return r;
918
919 r = mailimap_date_year_send(fd, date_time->dt_month);
920 if (r != MAILIMAP_NO_ERROR)
921 return r;
922
923 r = mailimap_space_send(fd);
924 if (r != MAILIMAP_NO_ERROR)
925 return r;
926
927 r = mailimap_fixed_digit_send(fd, date_time->dt_hour, 2);
928 if (r != MAILIMAP_NO_ERROR)
929 return r;
930
931 r = mailimap_char_send(fd, ':');
932 if (r != MAILIMAP_NO_ERROR)
933 return r;
934
935 r = mailimap_fixed_digit_send(fd, date_time->dt_min, 2);
936 if (r != MAILIMAP_NO_ERROR)
937 return r;
938
939 r = mailimap_char_send(fd, ':');
940 if (r != MAILIMAP_NO_ERROR)
941 return r;
942
943 r = mailimap_fixed_digit_send(fd, date_time->dt_sec, 2);
944 if (r != MAILIMAP_NO_ERROR)
945 return r;
946
947 return MAILIMAP_NO_ERROR;
948}
949
950/*
951=> delete = "DELETE" SP mailbox
952 ; Use of INBOX gives a NO error
953*/
954
955int mailimap_delete_send(mailstream * fd, const char * mb)
956{
957 int r;
958
959 r = mailimap_token_send(fd, "DELETE");
960 if (r != MAILIMAP_NO_ERROR)
961 return r;
962
963 r = mailimap_space_send(fd);
964 if (r != MAILIMAP_NO_ERROR)
965 return r;
966
967 r = mailimap_mailbox_send(fd, mb);
968 if (r != MAILIMAP_NO_ERROR)
969 return r;
970
971 return MAILIMAP_NO_ERROR;
972}
973
974/*
975
976digit
977
978digit-nz = %x31-39
979 ; 1-9
980*/
981
982static int mailimap_digit_send(mailstream * fd, int digit)
983{
984 return mailimap_char_send(fd, digit + '0');
985}
986
987
988/*
989 envelope = "(" env-date SP env-subject SP env-from SP env-sender SP
990 env-reply-to SP env-to SP env-cc SP env-bcc SP
991 env-in-reply-to SP env-message-id ")"
992
993 env-bcc = "(" 1*address ")" / nil
994
995 env-cc = "(" 1*address ")" / nil
996
997 env-date = nstring
998
999 env-from = "(" 1*address ")" / nil
1000
1001 env-in-reply-to = nstring
1002
1003 env-message-id = nstring
1004
1005 env-reply-to = "(" 1*address ")" / nil
1006
1007 env-sender = "(" 1*address ")" / nil
1008
1009 env-subject = nstring
1010
1011 env-to = "(" 1*address ")" / nil
1012*/
1013
1014/*
1015=> examine = "EXAMINE" SP mailbox
1016*/
1017
1018int mailimap_examine_send(mailstream * fd, const char * mb)
1019{
1020 int r;
1021
1022 r = mailimap_token_send(fd, "EXAMINE");
1023 if (r != MAILIMAP_NO_ERROR)
1024 return r;
1025
1026 r = mailimap_space_send(fd);
1027 if (r != MAILIMAP_NO_ERROR)
1028 return r;
1029
1030 r = mailimap_mailbox_send(fd, mb);
1031 if (r != MAILIMAP_NO_ERROR)
1032 return r;
1033
1034 return MAILIMAP_NO_ERROR;
1035}
1036
1037/*
1038=> fetch = "FETCH" SP set SP ("ALL" / "FULL" / "FAST" / fetch-att /
1039 "(" fetch-att *(SP fetch-att) ")")
1040*/
1041
1042static int
1043mailimap_fetch_att_list_send(mailstream * fd, clist * fetch_att_list);
1044
1045static int
1046mailimap_fetch_type_send(mailstream * fd,
1047 struct mailimap_fetch_type * fetch_type)
1048{
1049 switch (fetch_type->ft_type) {
1050 case MAILIMAP_FETCH_TYPE_ALL:
1051 return mailimap_token_send(fd, "ALL");
1052 case MAILIMAP_FETCH_TYPE_FULL:
1053 return mailimap_token_send(fd, "FULL");
1054 case MAILIMAP_FETCH_TYPE_FAST:
1055 return mailimap_token_send(fd, "FAST");
1056 case MAILIMAP_FETCH_TYPE_FETCH_ATT:
1057 return mailimap_fetch_att_send(fd, fetch_type->ft_data.ft_fetch_att);
1058 case MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST:
1059 return mailimap_fetch_att_list_send(fd,
1060 fetch_type->ft_data.ft_fetch_att_list);
1061 default:
1062 /* should not happen */
1063 return MAILIMAP_ERROR_INVAL;
1064 }
1065}
1066
1067int mailimap_fetch_send(mailstream * fd,
1068 struct mailimap_set * set,
1069 struct mailimap_fetch_type * fetch_type)
1070{
1071 int r;
1072
1073 r = mailimap_token_send(fd, "FETCH");
1074 if (r != MAILIMAP_NO_ERROR)
1075 return r;
1076
1077 r = mailimap_space_send(fd);
1078 if (r != MAILIMAP_NO_ERROR)
1079 return r;
1080
1081 r = mailimap_set_send(fd, set);
1082 if (r != MAILIMAP_NO_ERROR)
1083 return r;
1084
1085 r = mailimap_space_send(fd);
1086 if (r != MAILIMAP_NO_ERROR)
1087 return r;
1088
1089 r = mailimap_fetch_type_send(fd, fetch_type);
1090 if (r != MAILIMAP_NO_ERROR)
1091 return r;
1092
1093 return MAILIMAP_NO_ERROR;
1094}
1095
1096int
1097mailimap_uid_fetch_send(mailstream * fd,
1098 struct mailimap_set * set,
1099 struct mailimap_fetch_type * fetch_type)
1100{
1101 int r;
1102
1103 r = mailimap_token_send(fd, "UID");
1104 if (r != MAILIMAP_NO_ERROR)
1105 return r;
1106
1107 r = mailimap_space_send(fd);
1108 if (r != MAILIMAP_NO_ERROR)
1109 return r;
1110
1111 return mailimap_fetch_send(fd, set, fetch_type);
1112}
1113
1114/* currently porting */
1115
1116static int
1117mailimap_fetch_att_list_send(mailstream * fd, clist * fetch_att_list)
1118{
1119 int r;
1120
1121 r = mailimap_oparenth_send(fd);
1122 if (r != MAILIMAP_NO_ERROR)
1123 return r;
1124
1125 r = mailimap_struct_spaced_list_send(fd, fetch_att_list,
1126 (mailimap_struct_sender *)
1127 mailimap_fetch_att_send);
1128 if (r != MAILIMAP_NO_ERROR)
1129 return r;
1130
1131 r = mailimap_cparenth_send(fd);
1132 if (r != MAILIMAP_NO_ERROR)
1133 return r;
1134
1135 return MAILIMAP_NO_ERROR;
1136}
1137
1138/*
1139=> fetch-att = "ENVELOPE" / "FLAGS" / "INTERNALDATE" /
1140 "RFC822" [".HEADER" / ".SIZE" / ".TEXT"] /
1141 "BODY" ["STRUCTURE"] / "UID" /
1142 "BODY" [".PEEK"] section ["<" number "." nz-number ">"]
1143*/
1144
1145static int mailimap_fetch_att_send(mailstream * fd,
1146 struct mailimap_fetch_att * fetch_att)
1147{
1148 int r;
1149
1150 switch(fetch_att->att_type) {
1151 case MAILIMAP_FETCH_ATT_ENVELOPE:
1152 return mailimap_token_send(fd, "ENVELOPE");
1153
1154 case MAILIMAP_FETCH_ATT_FLAGS:
1155 return mailimap_token_send(fd, "FLAGS");
1156
1157 case MAILIMAP_FETCH_ATT_INTERNALDATE:
1158 return mailimap_token_send(fd, "INTERNALDATE");
1159
1160 case MAILIMAP_FETCH_ATT_RFC822:
1161 return mailimap_token_send(fd, "RFC822");
1162
1163 case MAILIMAP_FETCH_ATT_RFC822_HEADER:
1164 return mailimap_token_send(fd, "RFC822.HEADER");
1165
1166 case MAILIMAP_FETCH_ATT_RFC822_SIZE:
1167 return mailimap_token_send(fd, "RFC822.SIZE");
1168
1169 case MAILIMAP_FETCH_ATT_RFC822_TEXT:
1170 return mailimap_token_send(fd, "RFC822.TEXT");
1171
1172 case MAILIMAP_FETCH_ATT_BODY:
1173 return mailimap_token_send(fd, "BODY");
1174
1175 case MAILIMAP_FETCH_ATT_BODYSTRUCTURE:
1176 return mailimap_token_send(fd, "BODYSTRUCTURE");
1177
1178 case MAILIMAP_FETCH_ATT_UID:
1179 return mailimap_token_send(fd, "UID");
1180
1181 case MAILIMAP_FETCH_ATT_BODY_SECTION:
1182
1183 r = mailimap_token_send(fd, "BODY");
1184 if (r != MAILIMAP_NO_ERROR)
1185 return r;
1186 r = mailimap_section_send(fd, fetch_att->att_section);
1187 if (r != MAILIMAP_NO_ERROR)
1188 return r;
1189 if (fetch_att->att_size != 0) {
1190 r = mailimap_char_send(fd, '<');
1191 if (r != MAILIMAP_NO_ERROR)
1192 return r;
1193 r = mailimap_number_send(fd, fetch_att->att_offset);
1194 if (r != MAILIMAP_NO_ERROR)
1195 return r;
1196 r = mailimap_char_send(fd, '.');
1197 if (r != MAILIMAP_NO_ERROR)
1198 return r;
1199 r = mailimap_number_send(fd, fetch_att->att_size);
1200 if (r != MAILIMAP_NO_ERROR)
1201 return r;
1202 r = mailimap_char_send(fd, '>');
1203 if (r != MAILIMAP_NO_ERROR)
1204 return r;
1205 }
1206
1207 return MAILIMAP_NO_ERROR;
1208
1209 case MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION:
1210 r = mailimap_token_send(fd, "BODY.PEEK");
1211 if (r != MAILIMAP_NO_ERROR)
1212 return r;
1213 r = mailimap_section_send(fd, fetch_att->att_section);
1214 if (r != MAILIMAP_NO_ERROR)
1215 return r;
1216 if (fetch_att->att_size != 0) {
1217 r = mailimap_char_send(fd, '<');
1218 if (r != MAILIMAP_NO_ERROR)
1219 return r;
1220 r = mailimap_number_send(fd, fetch_att->att_offset);
1221 if (r != MAILIMAP_NO_ERROR)
1222 return r;
1223 r = mailimap_char_send(fd, '.');
1224 if (r != MAILIMAP_NO_ERROR)
1225 return r;
1226 r = mailimap_number_send(fd, fetch_att->att_size);
1227 if (r != MAILIMAP_NO_ERROR)
1228 return r;
1229 r = mailimap_char_send(fd, '>');
1230 if (r != MAILIMAP_NO_ERROR)
1231 return r;
1232 }
1233 return MAILIMAP_NO_ERROR;
1234
1235 default:
1236 /* should not happen */
1237 return MAILIMAP_ERROR_INVAL;
1238 }
1239}
1240
1241/*
1242=> flag = "\Answered" / "\Flagged" / "\Deleted" /
1243 "\Seen" / "\Draft" / flag-keyword / flag-extension
1244 ; Does not include "\Recent"
1245*/
1246
1247/*
1248enum {
1249 FLAG_ANSWERED,
1250 FLAG_FLAGGED,
1251 FLAG_DELETED,
1252 FLAG_SEEN,
1253 FLAG_DRAFT,
1254 FLAG_KEYWORD,
1255 FLAG_EXTENSION
1256};
1257
1258struct mailimap_flag {
1259 gint type;
1260 gchar * flag_keyword;
1261 gchar * flag_extension;
1262};
1263*/
1264
1265static int mailimap_flag_send(mailstream * fd,
1266 struct mailimap_flag * flag)
1267{
1268 switch(flag->fl_type) {
1269 case MAILIMAP_FLAG_ANSWERED:
1270 return mailimap_token_send(fd, "\\Answered");
1271 case MAILIMAP_FLAG_FLAGGED:
1272 return mailimap_token_send(fd, "\\Flagged");
1273 case MAILIMAP_FLAG_DELETED:
1274 return mailimap_token_send(fd, "\\Deleted");
1275 case MAILIMAP_FLAG_SEEN:
1276 return mailimap_token_send(fd, "\\Seen");
1277 case MAILIMAP_FLAG_DRAFT:
1278 return mailimap_token_send(fd, "\\Draft");
1279 case MAILIMAP_FLAG_KEYWORD:
1280 return mailimap_flag_keyword_send(fd, flag->fl_data.fl_keyword);
1281 case MAILIMAP_FLAG_EXTENSION:
1282 return mailimap_flag_extension_send(fd, flag->fl_data.fl_extension);
1283 default:
1284 /* should not happen */
1285 return MAILIMAP_ERROR_INVAL;
1286 }
1287}
1288
1289
1290/*
1291=> flag-extension = "\" atom
1292 ; Future expansion. Client implementations
1293 ; MUST accept flag-extension flags. Server
1294 ; implementations MUST NOT generate
1295 ; flag-extension flags except as defined by
1296 ; future standard or standards-track
1297 ; revisions of this specification.
1298*/
1299
1300static int mailimap_flag_extension_send(mailstream * fd,
1301 const char * flag_extension)
1302{
1303 int r;
1304
1305 r = mailimap_char_send(fd, '\\');
1306 if (r != MAILIMAP_NO_ERROR)
1307 return r;
1308
1309 r = mailimap_atom_send(fd, flag_extension);
1310 if (r != MAILIMAP_NO_ERROR)
1311 return r;
1312
1313 return MAILIMAP_NO_ERROR;
1314}
1315
1316/*
1317 flag-fetch = flag / "\Recent"
1318*/
1319
1320/*
1321=> flag-keyword = atom
1322*/
1323
1324static int mailimap_flag_keyword_send(mailstream * fd,
1325 const char * flag_keyword)
1326{
1327 return mailimap_token_send(fd, flag_keyword);
1328}
1329
1330/*
1331=> flag-list = "(" [flag *(SP flag)] ")"
1332*/
1333
1334static int mailimap_flag_list_send(mailstream * fd,
1335 struct mailimap_flag_list * flag_list)
1336{
1337 int r;
1338
1339 r = mailimap_oparenth_send(fd);
1340 if (r != MAILIMAP_NO_ERROR)
1341 return r;
1342
1343 if (flag_list->fl_list != NULL) {
1344 r = mailimap_struct_spaced_list_send(fd, flag_list->fl_list,
1345 (mailimap_struct_sender *) mailimap_flag_send);
1346 if (r != MAILIMAP_NO_ERROR)
1347 return r;
1348 }
1349
1350 r = mailimap_cparenth_send(fd);
1351 if (r != MAILIMAP_NO_ERROR)
1352 return r;
1353
1354 return MAILIMAP_NO_ERROR;
1355}
1356
1357/*
1358 flag-perm = flag / "\*"
1359
1360 greeting = "*" SP (resp-cond-auth / resp-cond-bye) CRLF
1361*/
1362
1363/*
1364=> header-fld-name = astring
1365*/
1366
1367static int mailimap_header_fld_name_send(mailstream * fd, const char * header)
1368{
1369 return mailimap_astring_send(fd, header);
1370}
1371
1372/*
1373=> header-list = "(" header-fld-name *(SP header-fld-name) ")"
1374*/
1375
1376static int
1377mailimap_header_list_send(mailstream * fd,
1378 struct mailimap_header_list * header_list)
1379{
1380 int r;
1381
1382 r = mailimap_oparenth_send(fd);
1383 if (r != MAILIMAP_NO_ERROR)
1384 return r;
1385
1386 r = mailimap_struct_spaced_list_send(fd, header_list->hdr_list,
1387 (mailimap_struct_sender *) mailimap_header_fld_name_send);
1388 if (r != MAILIMAP_NO_ERROR)
1389 return r;
1390
1391 r = mailimap_cparenth_send(fd);
1392 if (r != MAILIMAP_NO_ERROR)
1393 return r;
1394
1395 return MAILIMAP_NO_ERROR;
1396}
1397
1398/*
1399=> list = "LIST" SP mailbox SP list-mailbox
1400*/
1401
1402int mailimap_list_send(mailstream * fd,
1403 const char * mb,
1404 const char * list_mb)
1405{
1406 int r;
1407
1408 r = mailimap_token_send(fd, "LIST");
1409 if (r != MAILIMAP_NO_ERROR)
1410 return r;
1411
1412 r = mailimap_space_send(fd);
1413 if (r != MAILIMAP_NO_ERROR)
1414 return r;
1415
1416 r = mailimap_mailbox_send(fd, mb);
1417 if (r != MAILIMAP_NO_ERROR)
1418 return r;
1419
1420 r = mailimap_space_send(fd);
1421 if (r != MAILIMAP_NO_ERROR)
1422 return r;
1423
1424 r = mailimap_list_mailbox_send(fd, list_mb);
1425 if (r != MAILIMAP_NO_ERROR)
1426 return r;
1427
1428 return MAILIMAP_NO_ERROR;
1429}
1430
1431/*
1432=> list-mailbox = 1*list-char / string
1433*/
1434
1435static int
1436mailimap_list_mailbox_send(mailstream * fd, const char * pattern)
1437{
1438 return mailimap_quoted_send(fd, pattern);
1439}
1440
1441/*
1442 list-char = ATOM-CHAR / list-wildcards / resp-specials
1443
1444 list-wildcards = "%" / "*"
1445*/
1446
1447/*
1448=> literal = "{" number "}" CRLF *CHAR8
1449 ; Number represents the number of CHAR8s
1450*/
1451
1452int
1453mailimap_literal_send(mailstream * fd, const char * literal,
1454 size_t progr_rate,
1455 progress_function * progr_fun)
1456{
1457 uint32_t len;
1458 int r;
1459
1460 len = strlen(literal);
1461
1462 r = mailimap_literal_count_send(fd, len);
1463 if (r != MAILIMAP_NO_ERROR)
1464 return r;
1465 r = mailimap_literal_data_send(fd, literal, len, progr_rate, progr_fun);
1466 if (r != MAILIMAP_NO_ERROR)
1467 return r;
1468
1469 return MAILIMAP_NO_ERROR;
1470}
1471
1472/*
1473 "{" number "}" CRLF
1474*/
1475
1476int
1477mailimap_literal_count_send(mailstream * fd, uint32_t count)
1478{
1479 int r;
1480
1481 r = mailimap_char_send(fd, '{');
1482 if (r != MAILIMAP_NO_ERROR)
1483 return r;
1484
1485 r = mailimap_number_send(fd, count);
1486 if (r != MAILIMAP_NO_ERROR)
1487 return r;
1488
1489 r = mailimap_char_send(fd, '}');
1490 if (r != MAILIMAP_NO_ERROR)
1491 return r;
1492
1493 r = mailimap_crlf_send(fd);
1494 if (r != MAILIMAP_NO_ERROR)
1495 return r;
1496
1497 return MAILIMAP_NO_ERROR;
1498}
1499
1500/*
1501 *CHAR8
1502*/
1503
1504int
1505mailimap_literal_data_send(mailstream * fd, const char * literal, uint32_t len,
1506 size_t progr_rate,
1507 progress_function * progr_fun)
1508{
1509 int r;
1510
1511 r = mailimap_sized_token_send(fd, literal, len);
1512 if (r != MAILIMAP_NO_ERROR)
1513 return r;
1514
1515 return MAILIMAP_NO_ERROR;
1516}
1517
1518
1519/*
1520=> login = "LOGIN" SP userid SP password
1521*/
1522
1523int mailimap_login_send(mailstream * fd,
1524 const char * userid, const char * password)
1525{
1526 int r;
1527
1528 r = mailimap_token_send(fd, "LOGIN");
1529 if (r != MAILIMAP_NO_ERROR)
1530 return r;
1531
1532 r = mailimap_space_send(fd);
1533 if (r != MAILIMAP_NO_ERROR)
1534 return r;
1535
1536 r = mailimap_userid_send(fd, userid);
1537 if (r != MAILIMAP_NO_ERROR)
1538 return r;
1539
1540 r = mailimap_space_send(fd);
1541 if (r != MAILIMAP_NO_ERROR)
1542 return r;
1543
1544 r = mailimap_password_send(fd, password);
1545 if (r != MAILIMAP_NO_ERROR)
1546 return r;
1547
1548 return MAILIMAP_NO_ERROR;
1549}
1550
1551/*
1552=> lsub = "LSUB" SP mailbox SP list-mailbox
1553*/
1554
1555int mailimap_lsub_send(mailstream * fd,
1556 const char * mb, const char * list_mb)
1557{
1558 int r;
1559
1560 r = mailimap_token_send(fd, "LSUB");
1561 if (r != MAILIMAP_NO_ERROR)
1562 return r;
1563
1564 r = mailimap_space_send(fd);
1565 if (r != MAILIMAP_NO_ERROR)
1566 return r;
1567
1568 r = mailimap_mailbox_send(fd, mb);
1569 if (r != MAILIMAP_NO_ERROR)
1570 return r;
1571
1572 r = mailimap_space_send(fd);
1573 if (r != MAILIMAP_NO_ERROR)
1574 return r;
1575
1576 r = mailimap_list_mailbox_send(fd, list_mb);
1577 if (r != MAILIMAP_NO_ERROR)
1578 return r;
1579
1580 return MAILIMAP_NO_ERROR;
1581}
1582
1583/*
1584 mailbox = "INBOX" / astring
1585 ; INBOX is case-insensitive. All case variants of
1586 ; INBOX (e.g. "iNbOx") MUST be interpreted as INBOX
1587 ; not as an astring. An astring which consists of
1588 ; the case-insensitive sequence "I" "N" "B" "O" "X"
1589 ; is considered to be INBOX and not an astring.
1590 ; Refer to section 5.1 for further
1591 ; semantic details of mailbox names.
1592*/
1593
1594static int mailimap_mailbox_send(mailstream * fd, const char * mb)
1595{
1596 return mailimap_astring_send(fd, mb);
1597}
1598
1599/*
1600 mailbox-data = "FLAGS" SP flag-list / "LIST" SP mailbox-list /
1601 "LSUB" SP mailbox-list / "SEARCH" *(SP nz-number) /
1602 "STATUS" SP mailbox SP "("
1603 [status-att SP number *(SP status-att SP number)] ")" /
1604 number SP "EXISTS" / number SP "RECENT"
1605
1606 mailbox-list = "(" [mbx-list-flags] ")" SP
1607 (DQUOTE QUOTED-CHAR DQUOTE / nil) SP mailbox
1608
1609 mbx-list-flags = *(mbx-list-oflag SP) mbx-list-sflag
1610 *(SP mbx-list-oflag) /
1611 mbx-list-oflag *(SP mbx-list-oflag)
1612
1613 mbx-list-oflag = "\Noinferiors" / flag-extension
1614 ; Other flags; multiple possible per LIST response
1615
1616 mbx-list-sflag = "\Noselect" / "\Marked" / "\Unmarked"
1617 ; Selectability flags; only one per LIST response
1618
1619 media-basic = ((DQUOTE ("APPLICATION" / "AUDIO" / "IMAGE" / "MESSAGE" /
1620 "VIDEO") DQUOTE) / string) SP media-subtype
1621 ; Defined in [MIME-IMT]
1622
1623 media-message = DQUOTE "MESSAGE" DQUOTE SP DQUOTE "RFC822" DQUOTE
1624 ; Defined in [MIME-IMT]
1625
1626 media-subtype = string
1627 ; Defined in [MIME-IMT]
1628
1629 media-text = DQUOTE "TEXT" DQUOTE SP media-subtype
1630 ; Defined in [MIME-IMT]
1631
1632 message-data = nz-number SP ("EXPUNGE" / ("FETCH" SP msg-att))
1633
1634 msg-att = "(" (msg-att-dynamic / msg-att-static)
1635 *(SP (msg-att-dynamic / msg-att-static)) ")"
1636
1637 msg-att-dynamic = "FLAGS" SP "(" [flag-fetch *(SP flag-fetch)] ")"
1638 ; MAY change for a message
1639
1640 msg-att-static = "ENVELOPE" SP envelope / "INTERNALDATE" SP date-time /
1641 "RFC822" [".HEADER" / ".TEXT"] SP nstring /
1642 "RFC822.SIZE" SP number / "BODY" ["STRUCTURE"] SP body /
1643 "BODY" section ["<" number ">"] SP nstring /
1644 "UID" SP uniqueid
1645 ; MUST NOT change for a message
1646
1647 nil = "NIL"
1648
1649 nstring = string / nil
1650*/
1651
1652/*
1653=> number = 1*DIGIT
1654 ; Unsigned 32-bit integer
1655 ; (0 <= n < 4,294,967,296)
1656*/
1657
1658/*
1659 nz-number = digit-nz *DIGIT
1660 ; Non-zero unsigned 32-bit integer
1661 ; (0 < n < 4,294,967,296)
1662*/
1663
1664static int mailimap_number_send(mailstream * fd, uint32_t number)
1665{
1666 int r;
1667
1668 if (number / 10 != 0) {
1669 r = mailimap_number_send(fd, number / 10);
1670 if (r != MAILIMAP_NO_ERROR)
1671 return r;
1672 }
1673
1674 r = mailimap_digit_send(fd, number % 10);
1675 if (r != MAILIMAP_NO_ERROR)
1676 return r;
1677
1678 return MAILIMAP_NO_ERROR;
1679}
1680
1681/*
1682=> password = astring
1683*/
1684
1685static int mailimap_password_send(mailstream * fd, const char * pass)
1686{
1687 return mailimap_astring_send(fd, pass);
1688}
1689
1690/*
1691=> quoted = DQUOTE *QUOTED-CHAR DQUOTE
1692
1693=> QUOTED-CHAR = <any TEXT-CHAR except quoted-specials> /
1694 "\" quoted-specials
1695
1696=> quoted-specials = DQUOTE / "\"
1697*/
1698
1699static int is_quoted_specials(char ch)
1700{
1701 return (ch == '\"') || (ch == '\\');
1702}
1703
1704static int mailimap_quoted_char_send(mailstream * fd, char ch)
1705{
1706 int r;
1707
1708 if (is_quoted_specials(ch)) {
1709 r = mailimap_char_send(fd, '\\');
1710 if (r != MAILIMAP_NO_ERROR)
1711 return r;
1712 r = mailimap_char_send(fd, ch);
1713 if (r != MAILIMAP_NO_ERROR)
1714 return r;
1715
1716 return MAILIMAP_NO_ERROR;
1717 }
1718 else
1719 return mailimap_char_send(fd, ch);
1720}
1721
1722static int mailimap_quoted_send(mailstream * fd, const char * quoted)
1723{
1724 const char * pos;
1725 int r;
1726
1727 pos = quoted;
1728
1729 r = mailimap_dquote_send(fd);
1730 if (r != MAILIMAP_NO_ERROR)
1731 return r;
1732
1733 while (* pos != 0) {
1734 r = mailimap_quoted_char_send(fd, * pos);
1735 if (r != MAILIMAP_NO_ERROR)
1736 return r;
1737 pos ++;
1738 }
1739
1740 r = mailimap_dquote_send(fd);
1741 if (r != MAILIMAP_NO_ERROR)
1742 return r;
1743
1744 return MAILIMAP_NO_ERROR;
1745}
1746
1747/*
1748=> rename = "RENAME" SP mailbox SP mailbox
1749 ; Use of INBOX as a destination gives a NO error
1750*/
1751
1752int mailimap_rename_send(mailstream * fd, const char * mb,
1753 const char * new_name)
1754{
1755 int r;
1756
1757 r = mailimap_token_send(fd, "RENAME");
1758 if (r != MAILIMAP_NO_ERROR)
1759 return r;
1760 r = mailimap_space_send(fd);
1761 if (r != MAILIMAP_NO_ERROR)
1762 return r;
1763 r = mailimap_mailbox_send(fd, mb);
1764 if (r != MAILIMAP_NO_ERROR)
1765 return r;
1766 r = mailimap_space_send(fd);
1767 if (r != MAILIMAP_NO_ERROR)
1768 return r;
1769 r = mailimap_mailbox_send(fd, new_name);
1770 if (r != MAILIMAP_NO_ERROR)
1771 return r;
1772
1773 return MAILIMAP_NO_ERROR;
1774}
1775
1776/*
1777 response = *(continue-req / response-data) response-done
1778
1779 response-data = "*" SP (resp-cond-state / resp-cond-bye /
1780 mailbox-data / message-data / capability-data) CRLF
1781
1782 response-done = response-tagged / response-fatal
1783
1784 response-fatal = "*" SP resp-cond-bye CRLF
1785 ; Server closes connection immediately
1786
1787 response-tagged = tag SP resp-cond-state CRLF
1788
1789 resp-cond-auth = ("OK" / "PREAUTH") SP resp-text
1790 ; Authentication condition
1791
1792 resp-cond-bye = "BYE" SP resp-text
1793
1794 resp-cond-state = ("OK" / "NO" / "BAD") SP resp-text
1795 ; Status condition
1796
1797 resp-specials = "]"
1798
1799 resp-text = ["[" resp-text-code "]" SP] text
1800
1801 resp-text-code = "ALERT" /
1802 "BADCHARSET" [SP "(" astring *(SP astring) ")" ] /
1803 capability-data / "PARSE" /
1804 "PERMANENTFLAGS" SP "(" [flag-perm *(SP flag-perm)] ")" /
1805 "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
1806 "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
1807 "UNSEEN" SP nz-number /
1808 atom [SP 1*<any TEXT-CHAR except "]">]
1809*/
1810
1811/*
1812=> search = "SEARCH" [SP "CHARSET" SP astring] 1*(SP search-key)
1813 ; CHARSET argument to MUST be registered with IANA
1814*/
1815
1816int
1817mailimap_search_send(mailstream * fd, const char * charset,
1818 struct mailimap_search_key * key)
1819{
1820 int r;
1821
1822 r = mailimap_token_send(fd, "SEARCH");
1823 if (r != MAILIMAP_NO_ERROR)
1824 return r;
1825
1826 if (charset != NULL) {
1827 r = mailimap_space_send(fd);
1828 if (r != MAILIMAP_NO_ERROR)
1829 return r;
1830
1831 r = mailimap_token_send(fd, "CHARSET");
1832 if (r != MAILIMAP_NO_ERROR)
1833 return r;
1834 r = mailimap_space_send(fd);
1835 if (r != MAILIMAP_NO_ERROR)
1836 return r;
1837 r = mailimap_astring_send(fd, charset);
1838 if (r != MAILIMAP_NO_ERROR)
1839 return r;
1840 }
1841
1842 r = mailimap_space_send(fd);
1843 if (r != MAILIMAP_NO_ERROR)
1844 return r;
1845
1846 r = mailimap_search_key_send(fd, key);
1847 if (r != MAILIMAP_NO_ERROR)
1848 return r;
1849
1850 return MAILIMAP_NO_ERROR;
1851}
1852
1853int
1854mailimap_uid_search_send(mailstream * fd, const char * charset,
1855 struct mailimap_search_key * key)
1856{
1857 int r;
1858
1859 r = mailimap_token_send(fd, "UID");
1860 if (r != MAILIMAP_NO_ERROR)
1861 return r;
1862
1863 r = mailimap_space_send(fd);
1864 if (r != MAILIMAP_NO_ERROR)
1865 return r;
1866
1867 return mailimap_search_send(fd, charset, key);
1868}
1869
1870
1871/*
1872=> search-key = "ALL" / "ANSWERED" / "BCC" SP astring /
1873 "BEFORE" SP date / "BODY" SP astring /
1874 "CC" SP astring / "DELETED" / "FLAGGED" /
1875 "FROM" SP astring / "KEYWORD" SP flag-keyword / "NEW" /
1876 "OLD" / "ON" SP date / "RECENT" / "SEEN" /
1877 "SINCE" SP date / "SUBJECT" SP astring /
1878 "TEXT" SP astring / "TO" SP astring /
1879 "UNANSWERED" / "UNDELETED" / "UNFLAGGED" /
1880 "UNKEYWORD" SP flag-keyword / "UNSEEN" /
1881 ; Above this line were in [IMAP2]
1882 "DRAFT" / "HEADER" SP header-fld-name SP astring /
1883 "LARGER" SP number / "NOT" SP search-key /
1884 "OR" SP search-key SP search-key /
1885 "SENTBEFORE" SP date / "SENTON" SP date /
1886 "SENTSINCE" SP date / "SMALLER" SP number /
1887 "UID" SP set / "UNDRAFT" / set /
1888 "(" search-key *(SP search-key) ")"
1889*/
1890
1891
1892static int mailimap_search_key_send(mailstream * fd,
1893 struct mailimap_search_key * key)
1894{
1895 int r;
1896
1897 switch (key->sk_type) {
1898
1899 case MAILIMAP_SEARCH_KEY_ALL:
1900 return mailimap_token_send(fd, "ALL");
1901
1902 case MAILIMAP_SEARCH_KEY_ANSWERED:
1903 return mailimap_token_send(fd, "ANSWERED");
1904
1905 case MAILIMAP_SEARCH_KEY_BCC:
1906 r = mailimap_token_send(fd, "BCC");
1907 if (r != MAILIMAP_NO_ERROR)
1908 return r;
1909 r = mailimap_space_send(fd);
1910 if (r != MAILIMAP_NO_ERROR)
1911 return r;
1912 r = mailimap_astring_send(fd, key->sk_data.sk_bcc);
1913 if (r != MAILIMAP_NO_ERROR)
1914 return r;
1915 return MAILIMAP_NO_ERROR;
1916
1917 case MAILIMAP_SEARCH_KEY_BEFORE:
1918 r = mailimap_token_send(fd, "BEFORE");
1919 if (r != MAILIMAP_NO_ERROR)
1920 return r;
1921 r = mailimap_space_send(fd);
1922 if (r != MAILIMAP_NO_ERROR)
1923 return r;
1924 r = mailimap_date_send(fd, key->sk_data.sk_before);
1925 if (r != MAILIMAP_NO_ERROR)
1926 return r;
1927 return MAILIMAP_NO_ERROR;
1928
1929 case MAILIMAP_SEARCH_KEY_BODY:
1930 r = mailimap_token_send(fd, "BODY");
1931 if (r != MAILIMAP_NO_ERROR)
1932 return r;
1933 r = mailimap_space_send(fd);
1934 if (r != MAILIMAP_NO_ERROR)
1935 return r;
1936 r = mailimap_astring_send(fd, key->sk_data.sk_body);
1937 if (r != MAILIMAP_NO_ERROR)
1938 return r;
1939 return MAILIMAP_NO_ERROR;
1940
1941 case MAILIMAP_SEARCH_KEY_CC:
1942 r = mailimap_token_send(fd, "CC");
1943 if (r != MAILIMAP_NO_ERROR)
1944 return r;
1945 r = mailimap_space_send(fd);
1946 if (r != MAILIMAP_NO_ERROR)
1947 return r;
1948 r = mailimap_astring_send(fd, key->sk_data.sk_cc);
1949 if (r != MAILIMAP_NO_ERROR)
1950 return r;
1951 return MAILIMAP_NO_ERROR;
1952
1953 case MAILIMAP_SEARCH_KEY_DELETED:
1954 return mailimap_token_send(fd, "DELETED");
1955
1956 case MAILIMAP_SEARCH_KEY_FLAGGED:
1957 return mailimap_token_send(fd, "FLAGGED");
1958
1959 case MAILIMAP_SEARCH_KEY_FROM:
1960 r = mailimap_token_send(fd, "FROM");
1961 if (r != MAILIMAP_NO_ERROR)
1962 return r;
1963 r = mailimap_space_send(fd);
1964 if (r != MAILIMAP_NO_ERROR)
1965 return r;
1966 r = mailimap_astring_send(fd, key->sk_data.sk_from);
1967 if (r != MAILIMAP_NO_ERROR)
1968 return r;
1969 return MAILIMAP_NO_ERROR;
1970
1971 case MAILIMAP_SEARCH_KEY_KEYWORD:
1972 r = mailimap_token_send(fd, "KEYWORD");
1973 if (r != MAILIMAP_NO_ERROR)
1974 return r;
1975 r = mailimap_space_send(fd);
1976 if (r != MAILIMAP_NO_ERROR)
1977 return r;
1978 r = mailimap_flag_keyword_send(fd, key->sk_data.sk_keyword);
1979 if (r != MAILIMAP_NO_ERROR)
1980 return r;
1981 return MAILIMAP_NO_ERROR;
1982
1983 case MAILIMAP_SEARCH_KEY_NEW:
1984 return mailimap_token_send(fd, "NEW");
1985
1986 case MAILIMAP_SEARCH_KEY_OLD:
1987 return mailimap_token_send(fd, "OLD");
1988
1989 case MAILIMAP_SEARCH_KEY_ON:
1990 r = mailimap_token_send(fd, "ON");
1991 if (r != MAILIMAP_NO_ERROR)
1992 return r;
1993 r = mailimap_space_send(fd);
1994 if (r != MAILIMAP_NO_ERROR)
1995 return r;
1996 r = mailimap_date_send(fd, key->sk_data.sk_on);
1997 if (r != MAILIMAP_NO_ERROR)
1998 return r;
1999 return MAILIMAP_NO_ERROR;
2000
2001 case MAILIMAP_SEARCH_KEY_RECENT:
2002 return mailimap_token_send(fd, "RECENT");
2003
2004 case MAILIMAP_SEARCH_KEY_SEEN:
2005 return mailimap_token_send(fd, "SEEN");
2006
2007 case MAILIMAP_SEARCH_KEY_SINCE:
2008 r = mailimap_token_send(fd, "SINCE");
2009 if (r != MAILIMAP_NO_ERROR)
2010 return r;
2011 r = mailimap_space_send(fd);
2012 if (r != MAILIMAP_NO_ERROR)
2013 return r;
2014 r = mailimap_date_send(fd, key->sk_data.sk_since);
2015 if (r != MAILIMAP_NO_ERROR)
2016 return r;
2017 return MAILIMAP_NO_ERROR;
2018
2019 case MAILIMAP_SEARCH_KEY_SUBJECT:
2020 r = mailimap_token_send(fd, "SUBJECT");
2021 if (r != MAILIMAP_NO_ERROR)
2022 return r;
2023 r = mailimap_space_send(fd);
2024 if (r != MAILIMAP_NO_ERROR)
2025 return r;
2026 r = mailimap_astring_send(fd, key->sk_data.sk_subject);
2027 if (r != MAILIMAP_NO_ERROR)
2028 return r;
2029 return MAILIMAP_NO_ERROR;
2030
2031 case MAILIMAP_SEARCH_KEY_TEXT:
2032 r = mailimap_token_send(fd, "TEXT");
2033 if (r != MAILIMAP_NO_ERROR)
2034 return r;
2035 r = mailimap_space_send(fd);
2036 if (r != MAILIMAP_NO_ERROR)
2037 return r;
2038 r = mailimap_astring_send(fd, key->sk_data.sk_text);
2039 if (r != MAILIMAP_NO_ERROR)
2040 return r;
2041 return MAILIMAP_NO_ERROR;
2042
2043 case MAILIMAP_SEARCH_KEY_TO:
2044 r = mailimap_token_send(fd, "TO");
2045 if (r != MAILIMAP_NO_ERROR)
2046 return r;
2047 r = mailimap_space_send(fd);
2048 if (r != MAILIMAP_NO_ERROR)
2049 return r;
2050 r = mailimap_astring_send(fd, key->sk_data.sk_text);
2051 if (r != MAILIMAP_NO_ERROR)
2052 return r;
2053 return MAILIMAP_NO_ERROR;
2054
2055 case MAILIMAP_SEARCH_KEY_UNANSWERED:
2056 return mailimap_token_send(fd, "UNANSWERED");
2057
2058 case MAILIMAP_SEARCH_KEY_UNDELETED:
2059 return mailimap_token_send(fd, "UNDELETED");
2060
2061 case MAILIMAP_SEARCH_KEY_UNFLAGGED:
2062 return mailimap_token_send(fd, "UNFLAGGED");
2063
2064 case MAILIMAP_SEARCH_KEY_UNKEYWORD:
2065 r = mailimap_token_send(fd, "UNKEYWORD");
2066 if (r != MAILIMAP_NO_ERROR)
2067 return r;
2068 r = mailimap_space_send(fd);
2069 if (r != MAILIMAP_NO_ERROR)
2070 return r;
2071 r = mailimap_flag_keyword_send(fd, key->sk_data.sk_keyword);
2072 if (r != MAILIMAP_NO_ERROR)
2073 return r;
2074 return MAILIMAP_NO_ERROR;
2075
2076 case MAILIMAP_SEARCH_KEY_UNSEEN:
2077 return mailimap_token_send(fd, "UNSEEN");
2078
2079 case MAILIMAP_SEARCH_KEY_DRAFT:
2080 return mailimap_token_send(fd, "DRAFT");
2081
2082 case MAILIMAP_SEARCH_KEY_HEADER:
2083 r = mailimap_token_send(fd, "HEADER");
2084 if (r != MAILIMAP_NO_ERROR)
2085 return r;
2086 r = mailimap_space_send(fd);
2087 if (r != MAILIMAP_NO_ERROR)
2088 return r;
2089 r = mailimap_header_fld_name_send(fd,
2090 key->sk_data.sk_header.sk_header_name);
2091 if (r != MAILIMAP_NO_ERROR)
2092 return r;
2093 r = mailimap_space_send(fd);
2094 if (r != MAILIMAP_NO_ERROR)
2095 return r;
2096 r = mailimap_astring_send(fd,
2097 key->sk_data.sk_header.sk_header_value);
2098 if (r != MAILIMAP_NO_ERROR)
2099 return r;
2100 return MAILIMAP_NO_ERROR;
2101
2102 case MAILIMAP_SEARCH_KEY_LARGER:
2103 r = mailimap_token_send(fd, "LARGER");
2104 if (r != MAILIMAP_NO_ERROR)
2105 return r;
2106 r = mailimap_space_send(fd);
2107 if (r != MAILIMAP_NO_ERROR)
2108 return r;
2109 r = mailimap_number_send(fd, key->sk_data.sk_larger);
2110 if (r != MAILIMAP_NO_ERROR)
2111 return r;
2112 return MAILIMAP_NO_ERROR;
2113
2114 case MAILIMAP_SEARCH_KEY_NOT:
2115 r = mailimap_token_send(fd, "NOT");
2116 if (r != MAILIMAP_NO_ERROR)
2117 return r;
2118 r = mailimap_space_send(fd);
2119 if (r != MAILIMAP_NO_ERROR)
2120 return r;
2121 r = mailimap_search_key_send(fd, key->sk_data.sk_not);
2122 if (r != MAILIMAP_NO_ERROR)
2123 return r;
2124 return MAILIMAP_NO_ERROR;
2125
2126 case MAILIMAP_SEARCH_KEY_OR:
2127 r = mailimap_token_send(fd, "OR");
2128 if (r != MAILIMAP_NO_ERROR)
2129 return r;
2130 r = mailimap_space_send(fd);
2131 if (r != MAILIMAP_NO_ERROR)
2132 return r;
2133 r = mailimap_search_key_send(fd, key->sk_data.sk_or.sk_or1);
2134 if (r != MAILIMAP_NO_ERROR)
2135 return r;
2136 r = mailimap_space_send(fd);
2137 if (r != MAILIMAP_NO_ERROR)
2138 return r;
2139 r = mailimap_search_key_send(fd, key->sk_data.sk_or.sk_or2);
2140 if (r != MAILIMAP_NO_ERROR)
2141 return r;
2142 return TRUE;
2143
2144 case MAILIMAP_SEARCH_KEY_SENTBEFORE:
2145 r = mailimap_token_send(fd, "SENTBEFORE");
2146 if (r != MAILIMAP_NO_ERROR)
2147 return r;
2148 r = mailimap_space_send(fd);
2149 if (r != MAILIMAP_NO_ERROR)
2150 return r;
2151 r = mailimap_date_send(fd, key->sk_data.sk_sentbefore);
2152 if (r != MAILIMAP_NO_ERROR)
2153 return r;
2154 return MAILIMAP_NO_ERROR;
2155
2156 case MAILIMAP_SEARCH_KEY_SENTON:
2157 r = mailimap_token_send(fd, "SENTON");
2158 if (r != MAILIMAP_NO_ERROR)
2159 return r;
2160 r = mailimap_space_send(fd);
2161 if (r != MAILIMAP_NO_ERROR)
2162 return r;
2163 r = mailimap_date_send(fd, key->sk_data.sk_senton);
2164 if (r != MAILIMAP_NO_ERROR)
2165 return r;
2166 return MAILIMAP_NO_ERROR;
2167
2168 case MAILIMAP_SEARCH_KEY_SENTSINCE:
2169 r = mailimap_token_send(fd, "SENTSINCE");
2170 if (r != MAILIMAP_NO_ERROR)
2171 return r;
2172 r = mailimap_space_send(fd);
2173 if (r != MAILIMAP_NO_ERROR)
2174 return r;
2175 r = mailimap_date_send(fd, key->sk_data.sk_sentsince);
2176 if (r != MAILIMAP_NO_ERROR)
2177 return r;
2178 return MAILIMAP_NO_ERROR;
2179
2180 case MAILIMAP_SEARCH_KEY_SMALLER:
2181 r = mailimap_token_send(fd, "SMALLER");
2182 if (r != MAILIMAP_NO_ERROR)
2183 return r;
2184 r = mailimap_space_send(fd);
2185 if (r != MAILIMAP_NO_ERROR)
2186 return r;
2187 r = mailimap_number_send(fd, key->sk_data.sk_smaller);
2188 if (r != MAILIMAP_NO_ERROR)
2189 return r;
2190 return MAILIMAP_NO_ERROR;
2191
2192 case MAILIMAP_SEARCH_KEY_UID:
2193 r = mailimap_token_send(fd, "UID");
2194 if (r != MAILIMAP_NO_ERROR)
2195 return r;
2196 r = mailimap_space_send(fd);
2197 if (r != MAILIMAP_NO_ERROR)
2198 return r;
2199 r = mailimap_set_send(fd, key->sk_data.sk_set);
2200 if (r != MAILIMAP_NO_ERROR)
2201 return r;
2202 return MAILIMAP_NO_ERROR;
2203
2204 case MAILIMAP_SEARCH_KEY_UNDRAFT:
2205 return mailimap_token_send(fd, "UNDRAFT");
2206
2207 case MAILIMAP_SEARCH_KEY_SET:
2208 return mailimap_set_send(fd, key->sk_data.sk_set);
2209
2210 case MAILIMAP_SEARCH_KEY_MULTIPLE:
2211 r = mailimap_oparenth_send(fd);
2212 if (r != MAILIMAP_NO_ERROR)
2213 return r;
2214
2215 r = mailimap_struct_spaced_list_send(fd, key->sk_data.sk_multiple,
2216 (mailimap_struct_sender *)
2217 mailimap_search_key_send);
2218 if (r != MAILIMAP_NO_ERROR)
2219 return r;
2220
2221 r = mailimap_cparenth_send(fd);
2222 if (r != MAILIMAP_NO_ERROR)
2223 return r;
2224
2225 return MAILIMAP_NO_ERROR;
2226 default:
2227 /* should not happend */
2228 return MAILIMAP_ERROR_INVAL;
2229 }
2230}
2231
2232/*
2233=> section = "[" [section-spec] "]"
2234*/
2235
2236static int
2237mailimap_section_send(mailstream * fd,
2238 struct mailimap_section * section)
2239{
2240 int r;
2241
2242 r = mailimap_char_send(fd, '[');
2243 if (r != MAILIMAP_NO_ERROR)
2244 return r;
2245
2246 if (section != NULL) {
2247 if (section->sec_spec != NULL) {
2248 r = mailimap_section_spec_send(fd, section->sec_spec);
2249 if (r != MAILIMAP_NO_ERROR)
2250 return r;
2251 }
2252 }
2253
2254 r = mailimap_char_send(fd, ']');
2255 if (r != MAILIMAP_NO_ERROR)
2256 return r;
2257
2258 return MAILIMAP_NO_ERROR;
2259}
2260
2261/*
2262=> section-msgtext = "HEADER" / "HEADER.FIELDS" [".NOT"] SP header-list /
2263 "TEXT"
2264 ; top-level or MESSAGE/RFC822 part
2265*/
2266
2267static int
2268mailimap_section_msgtext_send(mailstream * fd,
2269 struct mailimap_section_msgtext *
2270 section_msgtext)
2271{
2272 int r;
2273
2274 switch (section_msgtext->sec_type) {
2275 case MAILIMAP_SECTION_MSGTEXT_HEADER:
2276 return mailimap_token_send(fd, "HEADER");
2277
2278 case MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS:
2279 r = mailimap_token_send(fd, "HEADER.FIELDS");
2280 if (r != MAILIMAP_NO_ERROR)
2281 return r;
2282 r = mailimap_space_send(fd);
2283 if (r != MAILIMAP_NO_ERROR)
2284 return r;
2285 r = mailimap_header_list_send(fd, section_msgtext->sec_header_list);
2286 if (r != MAILIMAP_NO_ERROR)
2287 return r;
2288 return MAILIMAP_NO_ERROR;
2289
2290 case MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT:
2291 r = mailimap_token_send(fd, "HEADER.FIELDS.NOT");
2292 if (r != MAILIMAP_NO_ERROR)
2293 return r;
2294 r = mailimap_space_send(fd);
2295 if (r != MAILIMAP_NO_ERROR)
2296 return r;
2297 r = mailimap_header_list_send(fd, section_msgtext->sec_header_list);
2298 if (r != MAILIMAP_NO_ERROR)
2299 return r;
2300 return MAILIMAP_NO_ERROR;
2301
2302 case MAILIMAP_SECTION_MSGTEXT_TEXT:
2303 return mailimap_token_send(fd, "TEXT");
2304
2305 default:
2306 /* should not happend */
2307 return MAILIMAP_ERROR_INVAL;
2308 }
2309}
2310
2311/*
2312=> section-part = nz-number *("." nz-number)
2313 ; body part nesting
2314*/
2315
2316static int
2317mailimap_pnumber_send(mailstream * fd, uint32_t * pnumber)
2318{
2319 return mailimap_number_send(fd, * pnumber);
2320}
2321
2322static int
2323mailimap_section_part_send(mailstream * fd,
2324 struct mailimap_section_part * section)
2325{
2326 int r;
2327
2328 r = mailimap_struct_list_send(fd, section->sec_id, '.',
2329 (mailimap_struct_sender *) mailimap_pnumber_send);
2330 if (r != MAILIMAP_NO_ERROR)
2331 return r;
2332
2333 return MAILIMAP_NO_ERROR;
2334}
2335
2336/*
2337=> section-spec = section-msgtext / (section-part ["." section-text])
2338*/
2339
2340static int
2341mailimap_section_spec_send(mailstream * fd,
2342 struct mailimap_section_spec * section_spec)
2343{
2344 int r;
2345
2346 switch (section_spec->sec_type) {
2347 case MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT:
2348 return mailimap_section_msgtext_send(fd,
2349 section_spec->sec_data.sec_msgtext);
2350
2351 case MAILIMAP_SECTION_SPEC_SECTION_PART:
2352 r = mailimap_section_part_send(fd, section_spec->sec_data.sec_part);
2353 if (r != MAILIMAP_NO_ERROR)
2354 return r;
2355
2356 if (section_spec->sec_text != NULL) {
2357 r = mailimap_char_send(fd, '.');
2358 if (r != MAILIMAP_NO_ERROR)
2359 return r;
2360 r = mailimap_section_text_send(fd,
2361 section_spec->sec_text);
2362 if (r != MAILIMAP_NO_ERROR)
2363 return r;
2364 }
2365
2366 return MAILIMAP_NO_ERROR;
2367
2368 default:
2369 /* should not happen */
2370 return MAILIMAP_ERROR_INVAL;
2371 }
2372}
2373
2374/*
2375=> section-text = section-msgtext / "MIME"
2376 ; text other than actual body part (headers, etc.)
2377*/
2378
2379static int
2380mailimap_section_text_send(mailstream * fd,
2381 struct mailimap_section_text * section_text)
2382{
2383 switch (section_text->sec_type) {
2384 case MAILIMAP_SECTION_TEXT_SECTION_MSGTEXT:
2385 return mailimap_section_msgtext_send(fd, section_text->sec_msgtext);
2386
2387 case MAILIMAP_SECTION_TEXT_MIME:
2388 return mailimap_token_send(fd, "MIME");
2389
2390 default:
2391 /* should not happen */
2392 return MAILIMAP_NO_ERROR;
2393 }
2394}
2395
2396/*
2397=> select = "SELECT" SP mailbox
2398*/
2399
2400int
2401mailimap_select_send(mailstream * fd, const char * mb)
2402{
2403 int r;
2404
2405 r = mailimap_token_send(fd, "SELECT");
2406 if (r != MAILIMAP_NO_ERROR)
2407 return r;
2408 r = mailimap_space_send(fd);
2409 if (r != MAILIMAP_NO_ERROR)
2410 return r;
2411 r = mailimap_mailbox_send(fd, mb);
2412 if (r != MAILIMAP_NO_ERROR)
2413 return r;
2414
2415 return MAILIMAP_NO_ERROR;
2416}
2417
2418/*
2419=> sequence-num = nz-number / "*"
2420 ; * is the largest number in use. For message
2421 ; sequence numbers, it is the number of messages
2422 ; in the mailbox. For unique identifiers, it is
2423 ; the unique identifier of the last message in
2424 ; the mailbox.
2425*/
2426
2427/* if sequence_num == 0 then "*" */
2428
2429static int
2430mailimap_sequence_num_send(mailstream * fd, uint32_t sequence_num)
2431{
2432 if (sequence_num == 0)
2433 return mailimap_char_send(fd, '*');
2434 else
2435 return mailimap_number_send(fd, sequence_num);
2436}
2437
2438/*
2439=> set = sequence-num / (sequence-num ":" sequence-num) /
2440 (set "," set)
2441 ; Identifies a set of messages. For message
2442 ; sequence numbers, these are consecutive
2443 ; numbers from 1 to the number of messages in
2444 ; the mailbox
2445 ; Comma delimits individual numbers, colon
2446 ; delimits between two numbers inclusive.
2447 ; Example: 2,4:7,9,12:* is 2,4,5,6,7,9,12,13,
2448 ; 14,15 for a mailbox with 15 messages.
2449*/
2450
2451static int mailimap_set_item_send(mailstream * fd,
2452 struct mailimap_set_item * item)
2453{
2454 int r;
2455
2456 if (item->set_first == item->set_last)
2457 return mailimap_sequence_num_send(fd, item->set_first);
2458 else {
2459 r = mailimap_sequence_num_send(fd, item->set_first);
2460 if (r != MAILIMAP_NO_ERROR)
2461 return r;
2462 r = mailimap_char_send(fd, ':');
2463 if (r != MAILIMAP_NO_ERROR)
2464 return r;
2465 r = mailimap_sequence_num_send(fd, item->set_last);
2466 if (r != MAILIMAP_NO_ERROR)
2467 return r;
2468 return MAILIMAP_NO_ERROR;
2469 }
2470}
2471
2472static int mailimap_set_send(mailstream * fd,
2473 struct mailimap_set * set)
2474{
2475 return mailimap_struct_list_send(fd, set->set_list, ',',
2476 (mailimap_struct_sender *) mailimap_set_item_send);
2477}
2478
2479/*
2480=> status = "STATUS" SP mailbox SP "(" status-att *(SP status-att) ")"
2481*/
2482
2483static int
2484mailimap_status_att_list_send(mailstream * fd,
2485 struct mailimap_status_att_list * status_att_list)
2486{
2487 return mailimap_struct_spaced_list_send(fd, status_att_list->att_list,
2488 (mailimap_struct_sender *) mailimap_status_att_send);
2489}
2490
2491int
2492mailimap_status_send(mailstream * fd, const char * mb,
2493 struct mailimap_status_att_list * status_att_list)
2494{
2495 int r;
2496
2497 r = mailimap_token_send(fd, "STATUS");
2498 if (r != MAILIMAP_NO_ERROR)
2499 return r;
2500
2501 r = mailimap_space_send(fd);
2502 if (r != MAILIMAP_NO_ERROR)
2503 return r;
2504
2505 r = mailimap_mailbox_send(fd, mb);
2506 if (r != MAILIMAP_NO_ERROR)
2507 return r;
2508
2509 r = mailimap_space_send(fd);
2510 if (r != MAILIMAP_NO_ERROR)
2511 return r;
2512
2513 r = mailimap_char_send(fd, '(');
2514 if (r != MAILIMAP_NO_ERROR)
2515 return r;
2516
2517 r = mailimap_status_att_list_send(fd, status_att_list);
2518 if (r != MAILIMAP_NO_ERROR)
2519 return r;
2520
2521 r = mailimap_char_send(fd, ')');
2522 if (r != MAILIMAP_NO_ERROR)
2523 return r;
2524
2525 return MAILIMAP_NO_ERROR;
2526}
2527
2528/*
2529=> status-att = "MESSAGES" / "RECENT" / "UIDNEXT" / "UIDVALIDITY" /
2530 "UNSEEN"
2531*/
2532
2533
2534static int mailimap_status_att_send(mailstream * fd, int * status_att)
2535{
2536 const char * token;
2537
2538 token = mailimap_status_att_get_token_str(* status_att);
2539 if (token == NULL) {
2540 /* should not happen */
2541 return MAILIMAP_ERROR_INVAL;
2542 }
2543
2544 return mailimap_token_send(fd, token);
2545}
2546
2547/*
2548=> store = "STORE" SP set SP store-att-flags
2549*/
2550
2551int
2552mailimap_store_send(mailstream * fd,
2553 struct mailimap_set * set,
2554 struct mailimap_store_att_flags * store_att_flags)
2555{
2556 int r;
2557
2558 r = mailimap_token_send(fd, "STORE");
2559 if (r != MAILIMAP_NO_ERROR)
2560 return r;
2561 r = mailimap_space_send(fd);
2562 if (r != MAILIMAP_NO_ERROR)
2563 return r;
2564 r = mailimap_set_send(fd, set);
2565 if (r != MAILIMAP_NO_ERROR)
2566 return r;
2567 r = mailimap_space_send(fd);
2568 if (r != MAILIMAP_NO_ERROR)
2569 return r;
2570
2571 r = mailimap_store_att_flags_send(fd, store_att_flags);
2572 if (r != MAILIMAP_NO_ERROR)
2573 return r;
2574
2575 return MAILIMAP_NO_ERROR;
2576}
2577
2578int
2579mailimap_uid_store_send(mailstream * fd,
2580 struct mailimap_set * set,
2581 struct mailimap_store_att_flags * store_att_flags)
2582{
2583 int r;
2584
2585 r = mailimap_token_send(fd, "UID");
2586 if (r != MAILIMAP_NO_ERROR)
2587 return r;
2588 r = mailimap_space_send(fd);
2589 if (r != MAILIMAP_NO_ERROR)
2590 return r;
2591
2592 return mailimap_store_send(fd, set, store_att_flags);
2593}
2594
2595/*
2596=> store-att-flags = (["+" / "-"] "FLAGS" [".SILENT"]) SP
2597 (flag-list / (flag *(SP flag)))
2598*/
2599
2600static int
2601mailimap_store_att_flags_send(mailstream * fd,
2602 struct mailimap_store_att_flags * store_flags)
2603{
2604 int r;
2605
2606 switch (store_flags->fl_sign) {
2607 case 1:
2608 r = mailimap_char_send(fd, '+');
2609 if (r != MAILIMAP_NO_ERROR)
2610 return r;
2611 case -1:
2612 r = mailimap_char_send(fd, '-');
2613 if (r != MAILIMAP_NO_ERROR)
2614 return r;
2615 }
2616
2617 r = mailimap_token_send(fd, "FLAGS");
2618 if (r != MAILIMAP_NO_ERROR)
2619 return r;
2620
2621 if (store_flags->fl_silent) {
2622 r = mailimap_token_send(fd, ".SILENT");
2623 if (r != MAILIMAP_NO_ERROR)
2624 return r;
2625 }
2626
2627 r = mailimap_space_send(fd);
2628 if (r != MAILIMAP_NO_ERROR)
2629 return r;
2630
2631 r = mailimap_flag_list_send(fd, store_flags->fl_flag_list);
2632 if (r != MAILIMAP_NO_ERROR)
2633 return r;
2634
2635 return MAILIMAP_NO_ERROR;
2636}
2637
2638/*
2639 string = quoted / literal
2640*/
2641
2642/*
2643=> subscribe = "SUBSCRIBE" SP mailbox
2644*/
2645
2646int mailimap_subscribe_send(mailstream * fd, const char * mb)
2647{
2648 int r;
2649
2650 r = mailimap_token_send(fd, "SUBSCRIBE");
2651 if (r != MAILIMAP_NO_ERROR)
2652 return r;
2653
2654 r = mailimap_space_send(fd);
2655 if (r != MAILIMAP_NO_ERROR)
2656 return r;
2657
2658 r = mailimap_mailbox_send(fd, mb);
2659 if (r != MAILIMAP_NO_ERROR)
2660 return r;
2661
2662 return MAILIMAP_NO_ERROR;
2663}
2664
2665/*
2666=> tag = 1*<any ASTRING-CHAR except "+">
2667*/
2668
2669int mailimap_tag_send(mailstream * fd, const char * tag)
2670{
2671 return mailimap_token_send(fd, tag);
2672}
2673
2674/*
2675 text = 1*TEXT-CHAR
2676
2677 TEXT-CHAR = <any CHAR except CR and LF>
2678
2679 time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
2680 ; Hours minutes seconds
2681*/
2682
2683/*
2684=> uid = "UID" SP (copy / fetch / search / store)
2685 ; Unique identifiers used instead of message
2686 ; sequence numbers
2687
2688functions uid_copy, uid_fetch ...
2689*/
2690
2691
2692/*
2693 uniqueid = nz-number
2694 ; Strictly ascending
2695*/
2696
2697/*
2698=> unsubscribe = "UNSUBSCRIBE" SP mailbox
2699*/
2700
2701int mailimap_unsubscribe_send(mailstream * fd,
2702 const char * mb)
2703{
2704 int r;
2705
2706 r = mailimap_token_send(fd, "UNSUBSCRIBE");
2707 if (r != MAILIMAP_NO_ERROR)
2708 return r;
2709 r = mailimap_space_send(fd);
2710 if (r != MAILIMAP_NO_ERROR)
2711 return r;
2712 r = mailimap_mailbox_send(fd, mb);
2713 if (r != MAILIMAP_NO_ERROR)
2714 return r;
2715
2716 return MAILIMAP_NO_ERROR;
2717}
2718
2719int mailimap_starttls_send(mailstream * fd)
2720{
2721 return mailimap_token_send(fd, "STARTTLS");
2722}
2723
2724/*
2725=> userid = astring
2726*/
2727
2728static int mailimap_userid_send(mailstream * fd, const char * user)
2729{
2730 return mailimap_astring_send(fd, user);
2731}
2732
2733/*
2734 x-command = "X" atom <experimental command arguments>
2735
2736 zone = ("+" / "-") 4DIGIT
2737 ; Signed four-digit value of hhmm representing
2738 ; hours and minutes east of Greenwich (that is,
2739 ; the amount that the given time differs from
2740 ; Universal Time). Subtracting the timezone
2741 ; from the given time will give the UT form.
2742 ; The Universal Time zone is "+0000".
2743*/
diff --git a/kmicromail/libetpan/imap/mailimap_sender.h b/kmicromail/libetpan/imap/mailimap_sender.h
new file mode 100644
index 0000000..3fc30ea
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_sender.h
@@ -0,0 +1,164 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_SENDER_H
37
38#define MAILIMAP_SENDER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mailimap_types.h"
45
46int mailimap_append_send(mailstream * fd,
47 const char * mailbox,
48 struct mailimap_flag_list * flag_list,
49 struct mailimap_date_time * date_time,
50 size_t literal_size);
51
52int mailimap_authenticate_send(mailstream * fd,
53 const char * auth_type);
54
55int mailimap_authenticate_resp_send(mailstream * fd,
56 const char * base64);
57
58int mailimap_noop_send(mailstream * fd);
59
60int mailimap_logout_send(mailstream * fd);
61
62int mailimap_capability_send(mailstream * fd);
63
64int mailimap_check_send(mailstream * fd);
65
66int mailimap_close_send(mailstream * fd);
67
68int mailimap_expunge_send(mailstream * fd);
69
70int mailimap_copy_send(mailstream * fd,
71 struct mailimap_set * set,
72 const char * mb);
73
74int mailimap_uid_copy_send(mailstream * fd,
75 struct mailimap_set * set,
76 const char * mb);
77
78int mailimap_create_send(mailstream * fd,
79 const char * mb);
80
81
82int mailimap_delete_send(mailstream * fd, const char * mb);
83
84int mailimap_examine_send(mailstream * fd, const char * mb);
85
86int
87mailimap_fetch_send(mailstream * fd,
88 struct mailimap_set * set,
89 struct mailimap_fetch_type * fetch_type);
90
91int
92mailimap_uid_fetch_send(mailstream * fd,
93 struct mailimap_set * set,
94 struct mailimap_fetch_type * fetch_type);
95
96int mailimap_list_send(mailstream * fd,
97 const char * mb, const char * list_mb);
98
99int mailimap_login_send(mailstream * fd,
100 const char * userid, const char * password);
101
102int mailimap_lsub_send(mailstream * fd,
103 const char * mb, const char * list_mb);
104
105int mailimap_rename_send(mailstream * fd, const char * mb,
106 const char * new_name);
107
108int
109mailimap_search_send(mailstream * fd, const char * charset,
110 struct mailimap_search_key * key);
111
112int
113mailimap_uid_search_send(mailstream * fd, const char * charset,
114 struct mailimap_search_key * key);
115
116int
117mailimap_select_send(mailstream * fd, const char * mb);
118
119int
120mailimap_status_send(mailstream * fd, const char * mb,
121 struct mailimap_status_att_list * status_att_list);
122
123int
124mailimap_store_send(mailstream * fd,
125 struct mailimap_set * set,
126 struct mailimap_store_att_flags * store_att_flags);
127
128int
129mailimap_uid_store_send(mailstream * fd,
130 struct mailimap_set * set,
131 struct mailimap_store_att_flags * store_att_flags);
132
133int mailimap_subscribe_send(mailstream * fd, const char * mb);
134
135
136int mailimap_tag_send(mailstream * fd, const char * tag);
137
138int mailimap_unsubscribe_send(mailstream * fd,
139 const char * mb);
140
141int mailimap_crlf_send(mailstream * fd);
142
143int mailimap_space_send(mailstream * fd);
144
145int
146mailimap_literal_send(mailstream * fd, const char * literal,
147 size_t progr_rate,
148 progress_function * progr_fun);
149
150int
151mailimap_literal_count_send(mailstream * fd, uint32_t count);
152
153int
154mailimap_literal_data_send(mailstream * fd, const char * literal, uint32_t len,
155 size_t progr_rate,
156 progress_function * progr_fun);
157
158int mailimap_starttls_send(mailstream * fd);
159
160#ifdef __cplusplus
161}
162#endif
163
164#endif
diff --git a/kmicromail/libetpan/imap/mailimap_socket.c b/kmicromail/libetpan/imap/mailimap_socket.c
new file mode 100644
index 0000000..6f846f2
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_socket.c
@@ -0,0 +1,73 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimap_socket.h"
37
38#include "mailimap.h"
39
40#include "connect.h"
41#include <netinet/in.h>
42#include <unistd.h>
43
44#define DEFAULT_IMAP_PORT 143
45#define SERVICE_NAME_IMAP "imap2"
46#define SERVICE_TYPE_TCP "tcp"
47
48int mailimap_socket_connect(mailimap * f, const char * server, uint16_t port)
49{
50 int s;
51 mailstream * stream;
52
53 if (port == 0) {
54 port = mail_get_service_port(SERVICE_NAME_IMAP, SERVICE_TYPE_TCP);
55 if (port == 0)
56 port = DEFAULT_IMAP_PORT;
57 port = ntohs(port);
58 }
59
60 /* Connection */
61
62 s = mail_tcp_connect(server, port);
63 if (s == -1)
64 return MAILIMAP_ERROR_CONNECTION_REFUSED;
65
66 stream = mailstream_socket_open(s);
67 if (stream == NULL) {
68 close(s);
69 return MAILIMAP_ERROR_MEMORY;
70 }
71
72 return mailimap_connect(f, stream);
73}
diff --git a/kmicromail/libetpan/imap/mailimap_socket.h b/kmicromail/libetpan/imap/mailimap_socket.h
new file mode 100644
index 0000000..aadc67e
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_socket.h
@@ -0,0 +1,54 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_SOCKET_H
37
38#define MAILIMAP_SOCKET_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45
46#include <libetpan/mailimap_types.h>
47
48int mailimap_socket_connect(mailimap * f, const char * server, uint16_t port);
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/kmicromail/libetpan/imap/mailimap_ssl.c b/kmicromail/libetpan/imap/mailimap_ssl.c
new file mode 100644
index 0000000..ace5678
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_ssl.c
@@ -0,0 +1,73 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimap_ssl.h"
37
38#include "mailimap.h"
39
40#include "connect.h"
41#include <netinet/in.h>
42#include <unistd.h>
43
44#define DEFAULT_IMAPS_PORT 993
45#define SERVICE_NAME_IMAPS "imaps"
46#define SERVICE_TYPE_TCP "tcp"
47
48int mailimap_ssl_connect(mailimap * f, const char * server, uint16_t port)
49{
50 int s;
51 mailstream * stream;
52
53 if (port == 0) {
54 port = mail_get_service_port(SERVICE_NAME_IMAPS, SERVICE_TYPE_TCP);
55 if (port == 0)
56 port = DEFAULT_IMAPS_PORT;
57 port = ntohs(port);
58 }
59
60 /* Connection */
61
62 s = mail_tcp_connect(server, port);
63 if (s == -1)
64 return MAILIMAP_ERROR_CONNECTION_REFUSED;
65
66 stream = mailstream_ssl_open(s);
67 if (stream == NULL) {
68 close(s);
69 return MAILIMAP_ERROR_CONNECTION_REFUSED;
70 }
71
72 return mailimap_connect(f, stream);
73}
diff --git a/kmicromail/libetpan/imap/mailimap_ssl.h b/kmicromail/libetpan/imap/mailimap_ssl.h
new file mode 100644
index 0000000..76906a0
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_ssl.h
@@ -0,0 +1,54 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_SSL_H
37
38#define MAILIMAP_SSL_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45
46#include <libetpan/mailimap_types.h>
47
48int mailimap_ssl_connect(mailimap * f, const char * server, uint16_t port);
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/kmicromail/libetpan/imap/mailimap_types.c b/kmicromail/libetpan/imap/mailimap_types.c
new file mode 100644
index 0000000..c5dde7c
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_types.c
@@ -0,0 +1,2961 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimap_types.h"
37#include "mmapstring.h"
38#include "mail.h"
39
40#include <stdlib.h>
41
42/* ************************************************************************* */
43/* ************************************************************************* */
44/* ************************************************************************* */
45/* ************************************************************************* */
46/* ************************************************************************* */
47/* ************************************************************************* */
48
49
50
51
52
53
54/* from parser */
55
56
57uint32_t * mailimap_number_alloc_new(uint32_t number)
58{
59 uint32_t * pnumber;
60
61 pnumber = malloc(sizeof(* pnumber));
62 if (pnumber == NULL)
63 return NULL;
64
65 * pnumber = number;
66
67 return pnumber;
68}
69
70void mailimap_number_alloc_free(uint32_t * pnumber)
71{
72 free(pnumber);
73}
74
75
76/* ************************************************************************* */
77
78
79struct mailimap_address *
80mailimap_address_new(char * ad_personal_name, char * ad_source_route,
81 char * ad_mailbox_name, char * ad_host_name)
82{
83 struct mailimap_address * addr;
84
85 addr = malloc(sizeof(* addr));
86 if (addr == NULL)
87 return NULL;
88
89 addr->ad_personal_name = ad_personal_name;
90 addr->ad_source_route = ad_source_route;
91 addr->ad_mailbox_name = ad_mailbox_name;
92 addr->ad_host_name = ad_host_name;
93
94 return addr;
95}
96
97void mailimap_address_free(struct mailimap_address * addr)
98{
99 mailimap_addr_host_free(addr->ad_host_name);
100 mailimap_addr_mailbox_free(addr->ad_mailbox_name);
101 mailimap_addr_adl_free(addr->ad_source_route);
102 mailimap_addr_name_free(addr->ad_personal_name);
103 free(addr);
104}
105
106void mailimap_addr_host_free(char * addr_host)
107{
108 mailimap_nstring_free(addr_host);
109}
110
111void mailimap_addr_mailbox_free(char * addr_mailbox)
112{
113 mailimap_nstring_free(addr_mailbox);
114}
115
116void mailimap_addr_adl_free(char * addr_adl)
117{
118 mailimap_nstring_free(addr_adl);
119}
120
121void mailimap_addr_name_free(char * addr_name)
122{
123 mailimap_nstring_free(addr_name);
124}
125
126
127
128
129
130/*
131struct mailimap_astring *
132mailimap_astring_new(gint type,
133 gchar * atom_astring,
134 gchar * string)
135{
136 struct mailimap_astring * astring;
137
138 astring = g_new(struct mailimap_astring, 1);
139 if (astring == NULL)
140 return FALSE;
141
142 astring->type = type;
143 astring->atom_astring = atom_astring;
144 astring->string = string;
145
146 return astring;
147}
148
149void mailimap_astring_free(struct mailimap_astring * astring)
150{
151 if (astring->atom_astring)
152 mailimap_atom_astring_free(astring->atom_astring);
153 if (astring->string)
154 mailimap_string_free(astring->string);
155 free(astring);
156}
157*/
158
159void mailimap_astring_free(char * astring)
160{
161 if (mmap_string_unref(astring) != 0)
162 free(astring);
163}
164
165static void mailimap_custom_string_free(char * str)
166{
167 free(str);
168}
169
170
171void mailimap_atom_free(char * atom)
172{
173 free(atom);
174}
175
176
177
178
179void mailimap_auth_type_free(char * auth_type)
180{
181 mailimap_atom_free(auth_type);
182}
183
184
185
186
187
188void mailimap_base64_free(char * base64)
189{
190 free(base64);
191}
192
193
194
195
196struct mailimap_body *
197mailimap_body_new(int bd_type,
198 struct mailimap_body_type_1part * bd_body_1part,
199 struct mailimap_body_type_mpart * bd_body_mpart)
200{
201 struct mailimap_body * body;
202
203 body = malloc(sizeof(* body));
204 if (body == NULL)
205 return NULL;
206
207 body->bd_type = bd_type;
208 switch (bd_type) {
209 case MAILIMAP_BODY_1PART:
210 body->bd_data.bd_body_1part = bd_body_1part;
211 break;
212 case MAILIMAP_BODY_MPART:
213 body->bd_data.bd_body_mpart = bd_body_mpart;
214 break;
215 }
216
217 return body;
218}
219
220void mailimap_body_free(struct mailimap_body * body)
221{
222 switch (body->bd_type) {
223 case MAILIMAP_BODY_1PART:
224 mailimap_body_type_1part_free(body->bd_data.bd_body_1part);
225 break;
226 case MAILIMAP_BODY_MPART:
227 mailimap_body_type_mpart_free(body->bd_data.bd_body_mpart);
228 break;
229 }
230 free(body);
231}
232
233
234struct mailimap_body_extension *
235mailimap_body_extension_new(int ext_type, char * ext_nstring,
236 uint32_t ext_number,
237 clist * ext_body_extension_list)
238{
239 struct mailimap_body_extension * body_extension;
240
241 body_extension = malloc(sizeof(* body_extension));
242 if (body_extension == NULL)
243 return NULL;
244
245 body_extension->ext_type = ext_type;
246 switch (ext_type) {
247 case MAILIMAP_BODY_EXTENSION_NSTRING:
248 body_extension->ext_data.ext_nstring = ext_nstring;
249 break;
250 case MAILIMAP_BODY_EXTENSION_NUMBER:
251 body_extension->ext_data.ext_number = ext_number;
252 break;
253 case MAILIMAP_BODY_EXTENSION_LIST:
254 body_extension->ext_data.ext_body_extension_list = ext_body_extension_list;
255 break;
256 }
257
258 return body_extension;
259}
260
261static void
262mailimap_body_ext_list_free(clist * body_ext_list);
263
264void mailimap_body_extension_free(struct mailimap_body_extension * be)
265{
266 switch (be->ext_type) {
267 case MAILIMAP_BODY_EXTENSION_NSTRING:
268 mailimap_nstring_free(be->ext_data.ext_nstring);
269 break;
270 case MAILIMAP_BODY_EXTENSION_LIST:
271 mailimap_body_ext_list_free(be->ext_data.ext_body_extension_list);
272 break;
273 }
274
275 free(be);
276}
277
278
279static void
280mailimap_body_ext_list_free(clist * body_ext_list)
281{
282 clist_foreach(body_ext_list, (clist_func) mailimap_body_extension_free,
283 NULL);
284 clist_free(body_ext_list);
285}
286
287
288struct mailimap_body_ext_1part *
289mailimap_body_ext_1part_new(char * bd_md5,
290 struct mailimap_body_fld_dsp * bd_disposition,
291 struct mailimap_body_fld_lang * bd_language,
292 clist * bd_extension_list)
293{
294 struct mailimap_body_ext_1part * body_ext_1part;
295
296 body_ext_1part = malloc(sizeof(* body_ext_1part));
297 if (body_ext_1part == NULL)
298 return NULL;
299
300 body_ext_1part->bd_md5 = bd_md5;
301 body_ext_1part->bd_disposition = bd_disposition;
302 body_ext_1part->bd_language = bd_language;
303 body_ext_1part->bd_extension_list = bd_extension_list;
304
305 return body_ext_1part;
306}
307
308void
309mailimap_body_ext_1part_free(struct mailimap_body_ext_1part * body_ext_1part)
310{
311 mailimap_body_fld_md5_free(body_ext_1part->bd_md5);
312 if (body_ext_1part->bd_disposition)
313 mailimap_body_fld_dsp_free(body_ext_1part->bd_disposition);
314 if (body_ext_1part->bd_language)
315 mailimap_body_fld_lang_free(body_ext_1part->bd_language);
316 if (body_ext_1part->bd_extension_list)
317 mailimap_body_ext_list_free(body_ext_1part->bd_extension_list);
318
319 free(body_ext_1part);
320}
321
322struct mailimap_body_ext_mpart *
323mailimap_body_ext_mpart_new(struct mailimap_body_fld_param * bd_parameter,
324 struct mailimap_body_fld_dsp * bd_disposition,
325 struct mailimap_body_fld_lang * bd_language,
326 clist * bd_extension_list)
327{
328 struct mailimap_body_ext_mpart * body_ext_mpart;
329
330 body_ext_mpart = malloc(sizeof(* body_ext_mpart));
331 if (body_ext_mpart == NULL)
332 return NULL;
333
334 body_ext_mpart->bd_parameter = bd_parameter;
335 body_ext_mpart->bd_disposition = bd_disposition;
336 body_ext_mpart->bd_language = bd_language;
337 body_ext_mpart->bd_extension_list = bd_extension_list;
338
339 return body_ext_mpart;
340}
341
342void
343mailimap_body_ext_mpart_free(struct mailimap_body_ext_mpart * body_ext_mpart)
344{
345 if (body_ext_mpart->bd_parameter != NULL)
346 mailimap_body_fld_param_free(body_ext_mpart->bd_parameter);
347 if (body_ext_mpart->bd_disposition)
348 mailimap_body_fld_dsp_free(body_ext_mpart->bd_disposition);
349 if (body_ext_mpart->bd_language)
350 mailimap_body_fld_lang_free(body_ext_mpart->bd_language);
351 if (body_ext_mpart->bd_extension_list)
352 mailimap_body_ext_list_free(body_ext_mpart->bd_extension_list);
353 free(body_ext_mpart);
354}
355
356
357struct mailimap_body_fields *
358mailimap_body_fields_new(struct mailimap_body_fld_param * bd_parameter,
359 char * bd_id,
360 char * bd_description,
361 struct mailimap_body_fld_enc * bd_encoding,
362 uint32_t bd_size)
363{
364 struct mailimap_body_fields * body_fields;
365
366 body_fields = malloc(sizeof(* body_fields));
367 if (body_fields == NULL)
368 return NULL;
369 body_fields->bd_parameter = bd_parameter;
370 body_fields->bd_id = bd_id;
371 body_fields->bd_description = bd_description;
372 body_fields->bd_encoding = bd_encoding;
373 body_fields->bd_size = bd_size;
374
375 return body_fields;
376}
377
378void
379mailimap_body_fields_free(struct mailimap_body_fields * body_fields)
380{
381 if (body_fields->bd_parameter != NULL)
382 mailimap_body_fld_param_free(body_fields->bd_parameter);
383 mailimap_body_fld_id_free(body_fields->bd_id);
384 mailimap_body_fld_desc_free(body_fields->bd_description);
385 mailimap_body_fld_enc_free(body_fields->bd_encoding);
386 free(body_fields);
387}
388
389
390
391
392
393
394void mailimap_body_fld_desc_free(char * body_fld_desc)
395{
396 mailimap_nstring_free(body_fld_desc);
397}
398
399
400
401
402struct mailimap_body_fld_dsp *
403mailimap_body_fld_dsp_new(char * dsp_type,
404 struct mailimap_body_fld_param * dsp_attributes)
405{
406 struct mailimap_body_fld_dsp * body_fld_dsp;
407
408 body_fld_dsp = malloc(sizeof(* body_fld_dsp));
409 if (body_fld_dsp == NULL)
410 return NULL;
411
412 body_fld_dsp->dsp_type = dsp_type;
413 body_fld_dsp->dsp_attributes = dsp_attributes;
414
415 return body_fld_dsp;
416}
417
418void mailimap_body_fld_dsp_free(struct mailimap_body_fld_dsp * bfd)
419{
420 if (bfd->dsp_type != NULL)
421 mailimap_string_free(bfd->dsp_type);
422 if (bfd->dsp_attributes != NULL)
423 mailimap_body_fld_param_free(bfd->dsp_attributes);
424 free(bfd);
425}
426
427
428
429struct mailimap_body_fld_enc *
430mailimap_body_fld_enc_new(int enc_type, char * enc_value)
431{
432 struct mailimap_body_fld_enc * body_fld_enc;
433
434 body_fld_enc = malloc(sizeof(* body_fld_enc));
435 if (body_fld_enc == NULL)
436 return NULL;
437
438 body_fld_enc->enc_type = enc_type;
439 body_fld_enc->enc_value = enc_value;
440
441 return body_fld_enc;
442}
443
444void mailimap_body_fld_enc_free(struct mailimap_body_fld_enc * bfe)
445{
446 if (bfe->enc_value)
447 mailimap_string_free(bfe->enc_value);
448 free(bfe);
449}
450
451
452
453void mailimap_body_fld_id_free(char * body_fld_id)
454{
455 mailimap_nstring_free(body_fld_id);
456}
457
458
459
460struct mailimap_body_fld_lang *
461mailimap_body_fld_lang_new(int lg_type, char * lg_single, clist * lg_list)
462{
463 struct mailimap_body_fld_lang * fld_lang;
464
465 fld_lang = malloc(sizeof(* fld_lang));
466 if (fld_lang == NULL)
467 return NULL;
468
469 fld_lang->lg_type = lg_type;
470 switch (lg_type) {
471 case MAILIMAP_BODY_FLD_LANG_SINGLE:
472 fld_lang->lg_data.lg_single = lg_single;
473 break;
474 case MAILIMAP_BODY_FLD_LANG_LIST:
475 fld_lang->lg_data.lg_list = lg_list;
476 break;
477 }
478
479 return fld_lang;
480}
481
482void
483mailimap_body_fld_lang_free(struct mailimap_body_fld_lang * fld_lang)
484{
485 switch (fld_lang->lg_type) {
486 case MAILIMAP_BODY_FLD_LANG_SINGLE:
487 mailimap_nstring_free(fld_lang->lg_data.lg_single);
488 break;
489 case MAILIMAP_BODY_FLD_LANG_LIST:
490 clist_foreach(fld_lang->lg_data.lg_list,
491 (clist_func) mailimap_string_free, NULL);
492 clist_free(fld_lang->lg_data.lg_list);
493 break;
494 }
495 free(fld_lang);
496}
497
498
499
500void mailimap_body_fld_md5_free(char * body_fld_md5)
501{
502 mailimap_nstring_free(body_fld_md5);
503}
504
505
506
507struct mailimap_single_body_fld_param *
508mailimap_single_body_fld_param_new(char * pa_name, char * pa_value)
509{
510 struct mailimap_single_body_fld_param * param;
511
512 param = malloc(sizeof(* param));
513 if (param == NULL)
514 return NULL;
515 param->pa_name = pa_name;
516 param->pa_value = pa_value;
517
518 return param;
519}
520
521void
522mailimap_single_body_fld_param_free(struct mailimap_single_body_fld_param * p)
523{
524 mailimap_string_free(p->pa_name);
525 mailimap_string_free(p->pa_value);
526 free(p);
527}
528
529
530struct mailimap_body_fld_param *
531mailimap_body_fld_param_new(clist * pa_list)
532{
533 struct mailimap_body_fld_param * fld_param;
534
535 fld_param = malloc(sizeof(* fld_param));
536 if (fld_param == NULL)
537 return NULL;
538 fld_param->pa_list = pa_list;
539
540 return fld_param;
541}
542
543void
544mailimap_body_fld_param_free(struct mailimap_body_fld_param * fld_param)
545{
546 clist_foreach(fld_param->pa_list,
547 (clist_func) mailimap_single_body_fld_param_free, NULL);
548 clist_free(fld_param->pa_list);
549 free(fld_param);
550}
551
552
553struct mailimap_body_type_1part *
554mailimap_body_type_1part_new(int bd_type,
555 struct mailimap_body_type_basic * bd_type_basic,
556 struct mailimap_body_type_msg * bd_type_msg,
557 struct mailimap_body_type_text * bd_type_text,
558 struct mailimap_body_ext_1part * bd_ext_1part)
559{
560 struct mailimap_body_type_1part * body_type_1part;
561
562 body_type_1part = malloc(sizeof(* body_type_1part));
563 if (body_type_1part == NULL)
564 return NULL;
565
566 body_type_1part->bd_type = bd_type;
567 switch (bd_type) {
568 case MAILIMAP_BODY_TYPE_1PART_BASIC:
569 body_type_1part->bd_data.bd_type_basic = bd_type_basic;
570 break;
571 case MAILIMAP_BODY_TYPE_1PART_MSG:
572 body_type_1part->bd_data.bd_type_msg = bd_type_msg;
573 break;
574 case MAILIMAP_BODY_TYPE_1PART_TEXT:
575 body_type_1part->bd_data.bd_type_text = bd_type_text;
576 break;
577 }
578 body_type_1part->bd_ext_1part = bd_ext_1part;
579
580 return body_type_1part;
581}
582
583void
584mailimap_body_type_1part_free(struct mailimap_body_type_1part * bt1p)
585{
586 switch (bt1p->bd_type) {
587 case MAILIMAP_BODY_TYPE_1PART_BASIC:
588 mailimap_body_type_basic_free(bt1p->bd_data.bd_type_basic);
589 break;
590 case MAILIMAP_BODY_TYPE_1PART_MSG:
591 mailimap_body_type_msg_free(bt1p->bd_data.bd_type_msg);
592 break;
593 case MAILIMAP_BODY_TYPE_1PART_TEXT:
594 mailimap_body_type_text_free(bt1p->bd_data.bd_type_text);
595 break;
596 }
597 if (bt1p->bd_ext_1part)
598 mailimap_body_ext_1part_free(bt1p->bd_ext_1part);
599
600 free(bt1p);
601}
602
603
604
605struct mailimap_body_type_basic *
606mailimap_body_type_basic_new(struct mailimap_media_basic * bd_media_basic,
607 struct mailimap_body_fields * bd_fields)
608{
609 struct mailimap_body_type_basic * body_type_basic;
610
611 body_type_basic = malloc(sizeof(* body_type_basic));
612 if (body_type_basic == NULL)
613 return NULL;
614
615 body_type_basic->bd_media_basic = bd_media_basic;
616 body_type_basic->bd_fields = bd_fields;
617
618 return body_type_basic;
619}
620
621void mailimap_body_type_basic_free(struct mailimap_body_type_basic *
622 body_type_basic)
623{
624 mailimap_media_basic_free(body_type_basic->bd_media_basic);
625 mailimap_body_fields_free(body_type_basic->bd_fields);
626 free(body_type_basic);
627}
628
629
630struct mailimap_body_type_mpart *
631mailimap_body_type_mpart_new(clist * bd_list, char * bd_media_subtype,
632 struct mailimap_body_ext_mpart * bd_ext_mpart)
633{
634 struct mailimap_body_type_mpart * body_type_mpart;
635
636 body_type_mpart = malloc(sizeof(* body_type_mpart));
637 if (body_type_mpart == NULL)
638 return NULL;
639
640 body_type_mpart->bd_list = bd_list;
641 body_type_mpart->bd_media_subtype = bd_media_subtype;
642 body_type_mpart->bd_ext_mpart = bd_ext_mpart;
643
644 return body_type_mpart;
645}
646
647void mailimap_body_type_mpart_free(struct mailimap_body_type_mpart *
648 body_type_mpart)
649{
650 clist_foreach(body_type_mpart->bd_list,
651 (clist_func) mailimap_body_free, NULL);
652 clist_free(body_type_mpart->bd_list);
653 mailimap_media_subtype_free(body_type_mpart->bd_media_subtype);
654 if (body_type_mpart->bd_ext_mpart)
655 mailimap_body_ext_mpart_free(body_type_mpart->bd_ext_mpart);
656
657 free(body_type_mpart);
658}
659
660
661struct mailimap_body_type_msg *
662mailimap_body_type_msg_new(struct mailimap_body_fields * bd_fields,
663 struct mailimap_envelope * bd_envelope,
664 struct mailimap_body * bd_body,
665 uint32_t bd_lines)
666{
667 struct mailimap_body_type_msg * body_type_msg;
668
669 body_type_msg = malloc(sizeof(* body_type_msg));
670 if (body_type_msg == NULL)
671 return NULL;
672
673 body_type_msg->bd_fields = bd_fields;
674 body_type_msg->bd_envelope = bd_envelope;
675 body_type_msg->bd_body = bd_body;
676 body_type_msg->bd_lines = bd_lines;
677
678 return body_type_msg;
679}
680
681void
682mailimap_body_type_msg_free(struct mailimap_body_type_msg * body_type_msg)
683{
684 mailimap_body_fields_free(body_type_msg->bd_fields);
685 mailimap_envelope_free(body_type_msg->bd_envelope);
686 mailimap_body_free(body_type_msg->bd_body);
687 free(body_type_msg);
688}
689
690
691
692struct mailimap_body_type_text *
693mailimap_body_type_text_new(char * bd_media_text,
694 struct mailimap_body_fields * bd_fields,
695 uint32_t bd_lines)
696{
697 struct mailimap_body_type_text * body_type_text;
698
699 body_type_text = malloc(sizeof(* body_type_text));
700 if (body_type_text == NULL)
701 return NULL;
702
703 body_type_text->bd_media_text = bd_media_text;
704 body_type_text->bd_fields = bd_fields;
705 body_type_text->bd_lines = bd_lines;
706
707 return body_type_text;
708}
709
710void
711mailimap_body_type_text_free(struct mailimap_body_type_text * body_type_text)
712{
713 mailimap_media_text_free(body_type_text->bd_media_text);
714 mailimap_body_fields_free(body_type_text->bd_fields);
715 free(body_type_text);
716}
717
718
719
720struct mailimap_capability *
721mailimap_capability_new(int cap_type, char * cap_auth_type, char * cap_name)
722{
723 struct mailimap_capability * cap;
724
725 cap = malloc(sizeof(* cap));
726 if (cap == NULL)
727 return NULL;
728 cap->cap_type = cap_type;
729 switch (cap_type) {
730 case MAILIMAP_CAPABILITY_AUTH_TYPE:
731 cap->cap_data.cap_auth_type = cap_auth_type;
732 break;
733 case MAILIMAP_CAPABILITY_NAME:
734 cap->cap_data.cap_name = cap_name;
735 break;
736 }
737
738 return cap;
739}
740
741void mailimap_capability_free(struct mailimap_capability * c)
742{
743 switch (c->cap_type) {
744 case MAILIMAP_CAPABILITY_AUTH_TYPE:
745 free(c->cap_data.cap_auth_type);
746 break;
747 case MAILIMAP_CAPABILITY_NAME:
748 free(c->cap_data.cap_name);
749 break;
750 }
751 free(c);
752}
753
754
755struct mailimap_capability_data *
756mailimap_capability_data_new(clist * cap_list)
757{
758 struct mailimap_capability_data * cap_data;
759
760 cap_data = malloc(sizeof(* cap_data));
761 if (cap_data == NULL)
762 return NULL;
763
764 cap_data->cap_list = cap_list;
765
766 return cap_data;
767}
768
769void
770mailimap_capability_data_free(struct mailimap_capability_data * cap_data)
771{
772 if (cap_data->cap_list) {
773 clist_foreach(cap_data->cap_list,
774 (clist_func) mailimap_capability_free, NULL);
775 clist_free(cap_data->cap_list);
776 }
777 free(cap_data);
778}
779
780
781
782
783struct mailimap_continue_req *
784mailimap_continue_req_new(int cr_type, struct mailimap_resp_text * cr_text,
785 char * cr_base64)
786{
787 struct mailimap_continue_req * cont_req;
788
789 cont_req = malloc(sizeof(* cont_req));
790 if (cont_req == NULL)
791 return NULL;
792 cont_req->cr_type = cr_type;
793 switch (cr_type) {
794 case MAILIMAP_CONTINUE_REQ_TEXT:
795 cont_req->cr_data.cr_text = cr_text;
796 break;
797 case MAILIMAP_CONTINUE_REQ_BASE64:
798 cont_req->cr_data.cr_base64 = cr_base64;
799 break;
800 }
801
802 return cont_req;
803}
804
805void mailimap_continue_req_free(struct mailimap_continue_req * cont_req)
806{
807 switch (cont_req->cr_type) {
808 case MAILIMAP_CONTINUE_REQ_TEXT:
809 mailimap_resp_text_free(cont_req->cr_data.cr_text);
810 break;
811 case MAILIMAP_CONTINUE_REQ_BASE64:
812 mailimap_base64_free(cont_req->cr_data.cr_base64);
813 break;
814 }
815 free(cont_req);
816}
817
818struct mailimap_date_time *
819mailimap_date_time_new(int dt_day, int dt_month, int dt_year, int dt_hour,
820 int dt_min, int dt_sec, int dt_zone)
821{
822 struct mailimap_date_time * date_time;
823
824 date_time = malloc(sizeof(* date_time));
825 if (date_time == NULL)
826 return NULL;
827
828 date_time->dt_day = dt_day;
829 date_time->dt_month = dt_month;
830 date_time->dt_year = dt_year;
831 date_time->dt_hour = dt_hour;
832 date_time->dt_min = dt_min;
833 date_time->dt_day = dt_sec;
834 date_time->dt_zone = dt_zone;
835
836 return date_time;
837}
838
839void mailimap_date_time_free(struct mailimap_date_time * date_time)
840{
841 free(date_time);
842}
843
844
845
846struct mailimap_envelope *
847mailimap_envelope_new(char * env_date, char * env_subject,
848 struct mailimap_env_from * env_from,
849 struct mailimap_env_sender * env_sender,
850 struct mailimap_env_reply_to * env_reply_to,
851 struct mailimap_env_to * env_to,
852 struct mailimap_env_cc* env_cc,
853 struct mailimap_env_bcc * env_bcc,
854 char * env_in_reply_to, char * env_message_id)
855{
856 struct mailimap_envelope * env;
857
858 env = malloc(sizeof(* env));
859 if (env == NULL)
860 return NULL;
861
862 env->env_date = env_date;
863 env->env_subject = env_subject;
864 env->env_from = env_from;
865 env->env_sender = env_sender;
866 env->env_reply_to = env_reply_to;
867 env->env_to = env_to;
868 env->env_cc = env_cc;
869 env->env_bcc = env_bcc;
870 env->env_in_reply_to = env_in_reply_to;
871 env->env_message_id = env_message_id;
872
873 return env;
874}
875
876
877void mailimap_envelope_free(struct mailimap_envelope * env)
878{
879 if (env->env_date)
880 mailimap_env_date_free(env->env_date);
881 if (env->env_subject)
882 mailimap_env_subject_free(env->env_subject);
883 if (env->env_from)
884 mailimap_env_from_free(env->env_from);
885 if (env->env_sender)
886 mailimap_env_sender_free(env->env_sender);
887 if (env->env_reply_to)
888 mailimap_env_reply_to_free(env->env_reply_to);
889 if (env->env_to)
890 mailimap_env_to_free(env->env_to);
891 if (env->env_cc)
892 mailimap_env_cc_free(env->env_cc);
893 if (env->env_bcc)
894 mailimap_env_bcc_free(env->env_bcc);
895 if (env->env_in_reply_to)
896 mailimap_env_in_reply_to_free(env->env_in_reply_to);
897 if (env->env_message_id)
898 mailimap_env_message_id_free(env->env_message_id);
899
900 free(env);
901}
902
903
904static void mailimap_address_list_free(clist * addr_list)
905{
906 if (addr_list != NULL) {
907 clist_foreach(addr_list, (clist_func) mailimap_address_free, NULL);
908 clist_free(addr_list);
909 }
910}
911
912
913struct mailimap_env_bcc * mailimap_env_bcc_new(clist * bcc_list)
914{
915 struct mailimap_env_bcc * env_bcc;
916
917 env_bcc = malloc(sizeof(* env_bcc));
918 if (env_bcc == NULL)
919 return NULL;
920 env_bcc->bcc_list = bcc_list;
921
922 return env_bcc;
923}
924
925void mailimap_env_bcc_free(struct mailimap_env_bcc * env_bcc)
926{
927 mailimap_address_list_free(env_bcc->bcc_list);
928 free(env_bcc);
929}
930
931
932struct mailimap_env_cc * mailimap_env_cc_new(clist * cc_list)
933{
934 struct mailimap_env_cc * env_cc;
935
936 env_cc = malloc(sizeof(* env_cc));
937 if (env_cc == NULL)
938 return NULL;
939 env_cc->cc_list = cc_list;
940
941 return env_cc;
942}
943
944void mailimap_env_cc_free(struct mailimap_env_cc * env_cc)
945{
946 mailimap_address_list_free(env_cc->cc_list);
947 free(env_cc);
948}
949
950
951void mailimap_env_date_free(char * date)
952{
953 mailimap_nstring_free(date);
954}
955
956
957struct mailimap_env_from * mailimap_env_from_new(clist * frm_list)
958{
959 struct mailimap_env_from * env_from;
960
961 env_from = malloc(sizeof(* env_from));
962 if (env_from == NULL)
963 return NULL;
964 env_from->frm_list = frm_list;
965
966 return env_from;
967}
968
969void mailimap_env_from_free(struct mailimap_env_from * env_from)
970{
971 mailimap_address_list_free(env_from->frm_list);
972 free(env_from);
973}
974
975
976void mailimap_env_in_reply_to_free(char * in_reply_to)
977{
978 mailimap_nstring_free(in_reply_to);
979}
980
981void mailimap_env_message_id_free(char * message_id)
982{
983 mailimap_nstring_free(message_id);
984}
985
986struct mailimap_env_reply_to * mailimap_env_reply_to_new(clist * rt_list)
987{
988 struct mailimap_env_reply_to * env_reply_to;
989
990 env_reply_to = malloc(sizeof(* env_reply_to));
991 if (env_reply_to == NULL)
992 return NULL;
993 env_reply_to->rt_list = rt_list;
994
995 return env_reply_to;
996}
997
998void
999mailimap_env_reply_to_free(struct mailimap_env_reply_to * env_reply_to)
1000{
1001 mailimap_address_list_free(env_reply_to->rt_list);
1002 free(env_reply_to);
1003}
1004
1005struct mailimap_env_sender * mailimap_env_sender_new(clist * snd_list)
1006{
1007 struct mailimap_env_sender * env_sender;
1008
1009 env_sender = malloc(sizeof(* env_sender));
1010 if (env_sender == NULL)
1011 return NULL;
1012 env_sender->snd_list = snd_list;
1013
1014 return env_sender;
1015}
1016
1017void mailimap_env_sender_free(struct mailimap_env_sender * env_sender)
1018{
1019 mailimap_address_list_free(env_sender->snd_list);
1020 free(env_sender);
1021}
1022
1023void mailimap_env_subject_free(char * subject)
1024{
1025 mailimap_nstring_free(subject);
1026}
1027
1028struct mailimap_env_to * mailimap_env_to_new(clist * to_list)
1029{
1030 struct mailimap_env_to * env_to;
1031
1032 env_to = malloc(sizeof(* env_to));
1033 if (env_to == NULL)
1034 return NULL;
1035 env_to->to_list = to_list;
1036
1037 return env_to;
1038}
1039
1040void mailimap_env_to_free(struct mailimap_env_to * env_to)
1041{
1042 mailimap_address_list_free(env_to->to_list);
1043 free(env_to);
1044}
1045
1046
1047
1048struct mailimap_flag * mailimap_flag_new(int fl_type,
1049 char * fl_keyword, char * fl_extension)
1050{
1051 struct mailimap_flag * f;
1052
1053 f = malloc(sizeof(* f));
1054 if (f == NULL)
1055 return NULL;
1056 f->fl_type = fl_type;
1057 switch (fl_type) {
1058 case MAILIMAP_FLAG_KEYWORD:
1059 f->fl_data.fl_keyword = fl_keyword;
1060 break;
1061 case MAILIMAP_FLAG_EXTENSION:
1062 f->fl_data.fl_extension = fl_extension;
1063 break;
1064 }
1065
1066 return f;
1067}
1068
1069void mailimap_flag_free(struct mailimap_flag * f)
1070{
1071 switch (f->fl_type) {
1072 case MAILIMAP_FLAG_KEYWORD:
1073 mailimap_flag_keyword_free(f->fl_data.fl_keyword);
1074 break;
1075 case MAILIMAP_FLAG_EXTENSION:
1076 mailimap_flag_extension_free(f->fl_data.fl_extension);
1077 break;
1078 }
1079 free(f);
1080}
1081
1082
1083
1084void mailimap_flag_extension_free(char * flag_extension)
1085{
1086 mailimap_atom_free(flag_extension);
1087}
1088
1089
1090
1091struct mailimap_flag_fetch *
1092mailimap_flag_fetch_new(int fl_type, struct mailimap_flag * fl_flag)
1093{
1094 struct mailimap_flag_fetch * flag_fetch;
1095
1096 flag_fetch = malloc(sizeof(* flag_fetch));
1097 if (flag_fetch == NULL)
1098 return NULL;
1099
1100 flag_fetch->fl_type = fl_type;
1101 flag_fetch->fl_flag = fl_flag;
1102
1103 return flag_fetch;
1104}
1105
1106void mailimap_flag_fetch_free(struct mailimap_flag_fetch * flag_fetch)
1107{
1108 if (flag_fetch->fl_flag)
1109 mailimap_flag_free(flag_fetch->fl_flag);
1110 free(flag_fetch);
1111}
1112
1113
1114
1115void mailimap_flag_keyword_free(char * flag_keyword)
1116{
1117 mailimap_atom_free(flag_keyword);
1118}
1119
1120
1121
1122
1123struct mailimap_flag_list *
1124mailimap_flag_list_new(clist * fl_list)
1125{
1126 struct mailimap_flag_list * flag_list;
1127
1128 flag_list = malloc(sizeof(* flag_list));
1129 if (flag_list == NULL)
1130 return NULL;
1131 flag_list->fl_list = fl_list;
1132
1133 return flag_list;
1134}
1135
1136void mailimap_flag_list_free(struct mailimap_flag_list * flag_list)
1137{
1138 clist_foreach(flag_list->fl_list, (clist_func) mailimap_flag_free, NULL);
1139 clist_free(flag_list->fl_list);
1140 free(flag_list);
1141}
1142
1143
1144
1145
1146
1147struct mailimap_flag_perm *
1148mailimap_flag_perm_new(int fl_type, struct mailimap_flag * fl_flag)
1149{
1150 struct mailimap_flag_perm * flag_perm;
1151
1152 flag_perm = malloc(sizeof(* flag_perm));
1153 if (flag_perm == NULL)
1154 return NULL;
1155
1156 flag_perm->fl_type = fl_type;
1157 flag_perm->fl_flag = fl_flag;
1158
1159 return flag_perm;
1160}
1161
1162void mailimap_flag_perm_free(struct mailimap_flag_perm * flag_perm)
1163{
1164 if (flag_perm->fl_flag != NULL)
1165 mailimap_flag_free(flag_perm->fl_flag);
1166 free(flag_perm);
1167}
1168
1169
1170
1171
1172struct mailimap_greeting *
1173mailimap_greeting_new(int gr_type,
1174 struct mailimap_resp_cond_auth * gr_auth,
1175 struct mailimap_resp_cond_bye * gr_bye)
1176{
1177 struct mailimap_greeting * greeting;
1178
1179 greeting = malloc(sizeof(* greeting));
1180 if (greeting == NULL)
1181 return NULL;
1182 greeting->gr_type = gr_type;
1183 switch (gr_type) {
1184 case MAILIMAP_GREETING_RESP_COND_AUTH:
1185 greeting->gr_data.gr_auth = gr_auth;
1186 break;
1187 case MAILIMAP_GREETING_RESP_COND_BYE:
1188 greeting->gr_data.gr_bye = gr_bye;
1189 break;
1190 }
1191
1192 return greeting;
1193}
1194
1195void mailimap_greeting_free(struct mailimap_greeting * greeting)
1196{
1197 switch (greeting->gr_type) {
1198 case MAILIMAP_GREETING_RESP_COND_AUTH:
1199 mailimap_resp_cond_auth_free(greeting->gr_data.gr_auth);
1200 break;
1201 case MAILIMAP_GREETING_RESP_COND_BYE:
1202 mailimap_resp_cond_bye_free(greeting->gr_data.gr_bye);
1203 break;
1204 }
1205 free(greeting);
1206}
1207
1208
1209
1210void
1211mailimap_header_fld_name_free(char * header_fld_name)
1212{
1213 mailimap_astring_free(header_fld_name);
1214}
1215
1216
1217
1218struct mailimap_header_list *
1219mailimap_header_list_new(clist * hdr_list)
1220{
1221 struct mailimap_header_list * header_list;
1222
1223 header_list = malloc(sizeof(* header_list));
1224 if (header_list == NULL)
1225 return NULL;
1226
1227 header_list->hdr_list = hdr_list;
1228
1229 return header_list;
1230}
1231
1232void
1233mailimap_header_list_free(struct mailimap_header_list * header_list)
1234{
1235 clist_foreach(header_list->hdr_list,
1236 (clist_func) mailimap_header_fld_name_free,
1237 NULL);
1238 clist_free(header_list->hdr_list);
1239 free(header_list);
1240}
1241
1242
1243
1244void mailimap_literal_free(char * literal)
1245{
1246 /* free(literal); */
1247 mmap_string_unref(literal);
1248}
1249
1250void mailimap_mailbox_free(char * mb)
1251{
1252 mailimap_astring_free(mb);
1253}
1254
1255
1256
1257
1258struct mailimap_status_info *
1259mailimap_status_info_new(int st_att, uint32_t st_value)
1260{
1261 struct mailimap_status_info * info;
1262
1263 info = malloc(sizeof(* info));
1264 if (info == NULL)
1265 return NULL;
1266 info->st_att = st_att;
1267 info->st_value = st_value;
1268
1269 return info;
1270}
1271
1272void mailimap_status_info_free(struct mailimap_status_info * info)
1273{
1274 free(info);
1275}
1276
1277
1278
1279struct mailimap_mailbox_data_status *
1280mailimap_mailbox_data_status_new(char * st_mailbox,
1281 clist * st_info_list)
1282{
1283 struct mailimap_mailbox_data_status * mb_data_status;
1284
1285 mb_data_status = malloc(sizeof(* mb_data_status));
1286 if (mb_data_status == NULL)
1287 return NULL;
1288 mb_data_status->st_mailbox = st_mailbox;
1289 mb_data_status->st_info_list = st_info_list;
1290
1291 return mb_data_status;
1292}
1293
1294void
1295mailimap_mailbox_data_search_free(clist * data_search)
1296{
1297 clist_foreach(data_search, (clist_func) mailimap_number_alloc_free, NULL);
1298 clist_free(data_search);
1299}
1300
1301void
1302mailimap_mailbox_data_status_free(struct mailimap_mailbox_data_status * info)
1303{
1304 mailimap_mailbox_free(info->st_mailbox);
1305 clist_foreach(info->st_info_list, (clist_func) mailimap_status_info_free,
1306 NULL);
1307 clist_free(info->st_info_list);
1308 free(info);
1309}
1310
1311
1312static void
1313mailimap_mailbox_data_flags_free(struct mailimap_flag_list * flag_list)
1314{
1315 mailimap_flag_list_free(flag_list);
1316}
1317
1318static void
1319mailimap_mailbox_data_list_free(struct mailimap_mailbox_list * mb_list)
1320{
1321 mailimap_mailbox_list_free(mb_list);
1322}
1323
1324static void
1325mailimap_mailbox_data_lsub_free(struct mailimap_mailbox_list * mb_lsub)
1326{
1327 mailimap_mailbox_list_free(mb_lsub);
1328}
1329
1330
1331
1332
1333
1334
1335struct mailimap_mailbox_data *
1336mailimap_mailbox_data_new(int mbd_type, struct mailimap_flag_list * mbd_flags,
1337 struct mailimap_mailbox_list * mbd_list,
1338 struct mailimap_mailbox_list * mbd_lsub,
1339 clist * mbd_search,
1340 struct mailimap_mailbox_data_status * mbd_status,
1341 uint32_t mbd_exists,
1342 uint32_t mbd_recent)
1343{
1344 struct mailimap_mailbox_data * data;
1345
1346 data = malloc(sizeof(* data));
1347 if (data == NULL)
1348 return NULL;
1349
1350 data->mbd_type = mbd_type;
1351 switch (mbd_type) {
1352 case MAILIMAP_MAILBOX_DATA_FLAGS:
1353 data->mbd_data.mbd_flags = mbd_flags;
1354 break;
1355 case MAILIMAP_MAILBOX_DATA_LIST:
1356 data->mbd_data.mbd_list = mbd_list;
1357 break;
1358 case MAILIMAP_MAILBOX_DATA_LSUB:
1359 data->mbd_data.mbd_lsub = mbd_lsub;
1360 break;
1361 case MAILIMAP_MAILBOX_DATA_SEARCH:
1362 data->mbd_data.mbd_search = mbd_search;
1363 break;
1364 case MAILIMAP_MAILBOX_DATA_STATUS:
1365 data->mbd_data.mbd_status = mbd_status;
1366 break;
1367 case MAILIMAP_MAILBOX_DATA_EXISTS:
1368 data->mbd_data.mbd_exists = mbd_exists;
1369 break;
1370 case MAILIMAP_MAILBOX_DATA_RECENT:
1371 data->mbd_data.mbd_recent = mbd_recent;
1372 break;
1373 }
1374
1375 return data;
1376}
1377
1378void
1379mailimap_mailbox_data_free(struct mailimap_mailbox_data * mb_data)
1380{
1381 switch (mb_data->mbd_type) {
1382 case MAILIMAP_MAILBOX_DATA_FLAGS:
1383 if (mb_data->mbd_data.mbd_flags != NULL)
1384 mailimap_mailbox_data_flags_free(mb_data->mbd_data.mbd_flags);
1385 break;
1386 case MAILIMAP_MAILBOX_DATA_LIST:
1387 if (mb_data->mbd_data.mbd_list != NULL)
1388 mailimap_mailbox_data_list_free(mb_data->mbd_data.mbd_list);
1389 break;
1390 case MAILIMAP_MAILBOX_DATA_LSUB:
1391 if (mb_data->mbd_data.mbd_lsub != NULL)
1392 mailimap_mailbox_data_lsub_free(mb_data->mbd_data.mbd_lsub);
1393 break;
1394 case MAILIMAP_MAILBOX_DATA_SEARCH:
1395 if (mb_data->mbd_data.mbd_search != NULL)
1396 mailimap_mailbox_data_search_free(mb_data->mbd_data.mbd_search);
1397 break;
1398 case MAILIMAP_MAILBOX_DATA_STATUS:
1399 if (mb_data->mbd_data.mbd_status != NULL)
1400 mailimap_mailbox_data_status_free(mb_data->mbd_data.mbd_status);
1401 break;
1402 }
1403 free(mb_data);
1404}
1405
1406
1407
1408
1409
1410struct mailimap_mbx_list_flags *
1411mailimap_mbx_list_flags_new(int mbf_type, clist * mbf_oflags,
1412 int mbf_sflag)
1413{
1414 struct mailimap_mbx_list_flags * mbx_list_flags;
1415
1416 mbx_list_flags = malloc(sizeof(* mbx_list_flags));
1417 if (mbx_list_flags == NULL)
1418 return NULL;
1419
1420 mbx_list_flags->mbf_type = mbf_type;
1421 mbx_list_flags->mbf_oflags = mbf_oflags;
1422 mbx_list_flags->mbf_sflag = mbf_sflag;
1423
1424 return mbx_list_flags;
1425}
1426
1427void
1428mailimap_mbx_list_flags_free(struct mailimap_mbx_list_flags * mbx_list_flags)
1429{
1430 clist_foreach(mbx_list_flags->mbf_oflags,
1431 (clist_func) mailimap_mbx_list_oflag_free,
1432 NULL);
1433 clist_free(mbx_list_flags->mbf_oflags);
1434
1435 free(mbx_list_flags);
1436}
1437
1438
1439struct mailimap_mbx_list_oflag *
1440mailimap_mbx_list_oflag_new(int of_type, char * of_flag_ext)
1441{
1442 struct mailimap_mbx_list_oflag * oflag;
1443
1444 oflag = malloc(sizeof(* oflag));
1445 if (oflag == NULL)
1446 return NULL;
1447
1448 oflag->of_type = of_type;
1449 oflag->of_flag_ext = of_flag_ext;
1450
1451 return oflag;
1452}
1453
1454void
1455mailimap_mbx_list_oflag_free(struct mailimap_mbx_list_oflag * oflag)
1456{
1457 if (oflag->of_flag_ext != NULL)
1458 mailimap_flag_extension_free(oflag->of_flag_ext);
1459 free(oflag);
1460}
1461
1462
1463
1464struct mailimap_mailbox_list *
1465mailimap_mailbox_list_new(struct mailimap_mbx_list_flags * mbx_flags,
1466 char mb_delimiter, char * mb_name)
1467{
1468 struct mailimap_mailbox_list * mb_list;
1469
1470 mb_list = malloc(sizeof(* mb_list));
1471 if (mb_list == NULL)
1472 return NULL;
1473
1474 mb_list->mb_flag = mbx_flags;
1475 mb_list->mb_delimiter = mb_delimiter;
1476 mb_list->mb_name = mb_name;
1477
1478 return mb_list;
1479}
1480
1481void
1482mailimap_mailbox_list_free(struct mailimap_mailbox_list * mb_list)
1483{
1484 if (mb_list->mb_flag != NULL)
1485 mailimap_mbx_list_flags_free(mb_list->mb_flag);
1486 if (mb_list->mb_name != NULL)
1487 mailimap_mailbox_free(mb_list->mb_name);
1488 free(mb_list);
1489}
1490
1491
1492
1493struct mailimap_media_basic *
1494mailimap_media_basic_new(int med_type,
1495 char * med_basic_type, char * med_subtype)
1496{
1497 struct mailimap_media_basic * media_basic;
1498
1499 media_basic = malloc(sizeof(* media_basic));
1500 if (media_basic == NULL)
1501 return NULL;
1502 media_basic->med_type = med_type;
1503 media_basic->med_basic_type = med_basic_type;
1504 media_basic->med_subtype = med_subtype;
1505
1506 return media_basic;
1507}
1508
1509void
1510mailimap_media_basic_free(struct mailimap_media_basic * media_basic)
1511{
1512 mailimap_string_free(media_basic->med_basic_type);
1513 mailimap_media_subtype_free(media_basic->med_subtype);
1514 free(media_basic);
1515}
1516
1517
1518
1519void mailimap_media_subtype_free(char * media_subtype)
1520{
1521 mmap_string_unref(media_subtype);
1522}
1523
1524
1525void mailimap_media_text_free(char * media_text)
1526{
1527 mailimap_media_subtype_free(media_text);
1528}
1529
1530
1531
1532struct mailimap_message_data *
1533mailimap_message_data_new(uint32_t mdt_number, int mdt_type,
1534 struct mailimap_msg_att * mdt_msg_att)
1535{
1536 struct mailimap_message_data * msg_data;
1537
1538 msg_data = malloc(sizeof(* msg_data));
1539 if (msg_data == NULL)
1540 free(msg_data);
1541
1542 msg_data->mdt_number = mdt_number;
1543 msg_data->mdt_type = mdt_type;
1544 msg_data->mdt_msg_att = mdt_msg_att;
1545
1546 return msg_data;
1547}
1548
1549void
1550mailimap_message_data_free(struct mailimap_message_data * msg_data)
1551{
1552 if (msg_data->mdt_msg_att != NULL)
1553 mailimap_msg_att_free(msg_data->mdt_msg_att);
1554 free(msg_data);
1555}
1556
1557
1558
1559
1560struct mailimap_msg_att_item *
1561mailimap_msg_att_item_new(int att_type,
1562 struct mailimap_msg_att_dynamic * att_dyn,
1563 struct mailimap_msg_att_static * att_static)
1564{
1565 struct mailimap_msg_att_item * item;
1566
1567 item = malloc(sizeof(* item));
1568 if (item == NULL)
1569 return item;
1570
1571 item->att_type = att_type;
1572 switch (att_type) {
1573 case MAILIMAP_MSG_ATT_ITEM_DYNAMIC:
1574 item->att_data.att_dyn = att_dyn;
1575 break;
1576 case MAILIMAP_MSG_ATT_ITEM_STATIC:
1577 item->att_data.att_static = att_static;
1578 break;
1579 }
1580
1581 return item;
1582}
1583
1584void
1585mailimap_msg_att_item_free(struct mailimap_msg_att_item * item)
1586{
1587 switch (item->att_type) {
1588 case MAILIMAP_MSG_ATT_ITEM_DYNAMIC:
1589 mailimap_msg_att_dynamic_free(item->att_data.att_dyn);
1590 break;
1591 case MAILIMAP_MSG_ATT_ITEM_STATIC:
1592 mailimap_msg_att_static_free(item->att_data.att_static);
1593 break;
1594 }
1595 free(item);
1596}
1597
1598
1599struct mailimap_msg_att *
1600mailimap_msg_att_new(clist * att_list)
1601{
1602 struct mailimap_msg_att * msg_att;
1603
1604 msg_att = malloc(sizeof(* msg_att));
1605 if (msg_att == NULL)
1606 return NULL;
1607
1608 msg_att->att_list = att_list;
1609 msg_att->att_number = 0;
1610
1611 return msg_att;
1612}
1613
1614void mailimap_msg_att_free(struct mailimap_msg_att * msg_att)
1615{
1616 clist_foreach(msg_att->att_list,
1617 (clist_func) mailimap_msg_att_item_free, NULL);
1618 clist_free(msg_att->att_list);
1619 free(msg_att);
1620}
1621
1622
1623
1624struct mailimap_msg_att_dynamic *
1625mailimap_msg_att_dynamic_new(clist * att_list)
1626{
1627 struct mailimap_msg_att_dynamic * msg_att_dyn;
1628
1629 msg_att_dyn = malloc(sizeof(* msg_att_dyn));
1630 if (msg_att_dyn == NULL)
1631 return NULL;
1632
1633 msg_att_dyn->att_list = att_list;
1634
1635 return msg_att_dyn;
1636}
1637
1638void
1639mailimap_msg_att_dynamic_free(struct mailimap_msg_att_dynamic * msg_att_dyn)
1640{
1641 if (msg_att_dyn->att_list != NULL) {
1642 clist_foreach(msg_att_dyn->att_list,
1643 (clist_func) mailimap_flag_fetch_free,
1644 NULL);
1645 clist_free(msg_att_dyn->att_list);
1646 }
1647 free(msg_att_dyn);
1648}
1649
1650
1651struct mailimap_msg_att_body_section *
1652mailimap_msg_att_body_section_new(struct mailimap_section * sec_section,
1653 uint32_t sec_origin_octet,
1654 char * sec_body_part,
1655 size_t sec_length)
1656{
1657 struct mailimap_msg_att_body_section * msg_att_body_section;
1658
1659 msg_att_body_section = malloc(sizeof(* msg_att_body_section));
1660 if (msg_att_body_section == NULL)
1661 return NULL;
1662
1663 msg_att_body_section->sec_section = sec_section;
1664 msg_att_body_section->sec_origin_octet = sec_origin_octet;
1665 msg_att_body_section->sec_body_part = sec_body_part;
1666 msg_att_body_section->sec_length = sec_length;
1667
1668 return msg_att_body_section;
1669}
1670
1671void
1672mailimap_msg_att_body_section_free(struct mailimap_msg_att_body_section *
1673 msg_att_body_section)
1674{
1675 if (msg_att_body_section->sec_section != NULL)
1676 mailimap_section_free(msg_att_body_section->sec_section);
1677 if (msg_att_body_section->sec_body_part != NULL)
1678 mailimap_nstring_free(msg_att_body_section->sec_body_part);
1679 free(msg_att_body_section);
1680}
1681
1682
1683
1684
1685
1686
1687void mailimap_msg_att_envelope_free(struct mailimap_envelope * env)
1688{
1689 mailimap_envelope_free(env);
1690}
1691
1692void
1693mailimap_msg_att_internaldate_free(struct mailimap_date_time * date_time)
1694{
1695 mailimap_date_time_free(date_time);
1696}
1697
1698void
1699mailimap_msg_att_rfc822_free(char * str)
1700{
1701 mailimap_nstring_free(str);
1702}
1703
1704
1705void
1706mailimap_msg_att_rfc822_header_free(char * str)
1707{
1708 mailimap_nstring_free(str);
1709}
1710
1711void
1712mailimap_msg_att_rfc822_text_free(char * str)
1713{
1714 mailimap_nstring_free(str);
1715}
1716
1717void
1718mailimap_msg_att_body_free(struct mailimap_body * body)
1719{
1720 mailimap_body_free(body);
1721}
1722
1723void
1724mailimap_msg_att_bodystructure_free(struct mailimap_body * body)
1725{
1726 mailimap_body_free(body);
1727}
1728
1729
1730
1731struct mailimap_msg_att_static *
1732mailimap_msg_att_static_new(int att_type, struct mailimap_envelope * att_env,
1733 struct mailimap_date_time * att_internal_date,
1734 char * att_rfc822,
1735 char * att_rfc822_header,
1736 char * att_rfc822_text,
1737 size_t att_length,
1738 uint32_t att_rfc822_size,
1739 struct mailimap_body * att_bodystructure,
1740 struct mailimap_body * att_body,
1741 struct mailimap_msg_att_body_section * att_body_section,
1742 uint32_t att_uid)
1743{
1744 struct mailimap_msg_att_static * item;
1745
1746 item = malloc(sizeof(* item));
1747 if (item == NULL)
1748 return FALSE;
1749
1750 item->att_type = att_type;
1751 switch (att_type) {
1752 case MAILIMAP_MSG_ATT_ENVELOPE:
1753 item->att_data.att_env = att_env;
1754 break;
1755 case MAILIMAP_MSG_ATT_INTERNALDATE:
1756 item->att_data.att_internal_date = att_internal_date;
1757 break;
1758 case MAILIMAP_MSG_ATT_RFC822:
1759 item->att_data.att_rfc822.att_content = att_rfc822;
1760 item->att_data.att_rfc822.att_length = att_length;
1761 break;
1762 case MAILIMAP_MSG_ATT_RFC822_HEADER:
1763 item->att_data.att_rfc822_header.att_content = att_rfc822_header;
1764 item->att_data.att_rfc822_header.att_length = att_length;
1765 break;
1766 case MAILIMAP_MSG_ATT_RFC822_TEXT:
1767 item->att_data.att_rfc822_text.att_content = att_rfc822_text;
1768 item->att_data.att_rfc822_text.att_length = att_length;
1769 break;
1770 case MAILIMAP_MSG_ATT_RFC822_SIZE:
1771 item->att_data.att_rfc822_size = att_rfc822_size;
1772 break;
1773 case MAILIMAP_MSG_ATT_BODY:
1774 item->att_data.att_body = att_body;
1775 break;
1776 case MAILIMAP_MSG_ATT_BODYSTRUCTURE:
1777 item->att_data.att_bodystructure = att_bodystructure;
1778 break;
1779 case MAILIMAP_MSG_ATT_BODY_SECTION:
1780 item->att_data.att_body_section = att_body_section;
1781 break;
1782 case MAILIMAP_MSG_ATT_UID:
1783 item->att_data.att_uid = att_uid;
1784 break;
1785 }
1786
1787 return item;
1788}
1789
1790void
1791mailimap_msg_att_static_free(struct mailimap_msg_att_static * item)
1792{
1793 switch (item->att_type) {
1794 case MAILIMAP_MSG_ATT_ENVELOPE:
1795 if (item->att_data.att_env != NULL)
1796 mailimap_msg_att_envelope_free(item->att_data.att_env);
1797 break;
1798 case MAILIMAP_MSG_ATT_INTERNALDATE:
1799 if (item->att_data.att_internal_date != NULL)
1800 mailimap_msg_att_internaldate_free(item->att_data.att_internal_date);
1801 break;
1802 case MAILIMAP_MSG_ATT_RFC822:
1803 if (item->att_data.att_rfc822.att_content != NULL)
1804 mailimap_msg_att_rfc822_free(item->att_data.att_rfc822.att_content);
1805 break;
1806 case MAILIMAP_MSG_ATT_RFC822_HEADER:
1807 if (item->att_data.att_rfc822_header.att_content != NULL)
1808 mailimap_msg_att_rfc822_header_free(item->att_data.att_rfc822_header.att_content);
1809 break;
1810 case MAILIMAP_MSG_ATT_RFC822_TEXT:
1811 if (item->att_data.att_rfc822_text.att_content != NULL)
1812 mailimap_msg_att_rfc822_text_free(item->att_data.att_rfc822_text.att_content);
1813 break;
1814 case MAILIMAP_MSG_ATT_BODYSTRUCTURE:
1815 if (item->att_data.att_bodystructure != NULL)
1816 mailimap_msg_att_bodystructure_free(item->att_data.att_bodystructure);
1817 break;
1818 case MAILIMAP_MSG_ATT_BODY:
1819 if (item->att_data.att_body != NULL)
1820 mailimap_msg_att_body_free(item->att_data.att_body);
1821 break;
1822 case MAILIMAP_MSG_ATT_BODY_SECTION:
1823 if (item->att_data.att_body_section != NULL)
1824 mailimap_msg_att_body_section_free(item->att_data.att_body_section);
1825 break;
1826 }
1827 free(item);
1828}
1829
1830
1831
1832
1833void mailimap_nstring_free(char * str)
1834{
1835 if (str != NULL)
1836 mailimap_string_free(str);
1837}
1838
1839
1840
1841
1842
1843
1844
1845struct mailimap_cont_req_or_resp_data *
1846mailimap_cont_req_or_resp_data_new(int rsp_type,
1847 struct mailimap_continue_req * rsp_cont_req,
1848 struct mailimap_response_data * rsp_resp_data)
1849{
1850 struct mailimap_cont_req_or_resp_data * cont_req_or_resp_data;
1851
1852 cont_req_or_resp_data = malloc(sizeof(* cont_req_or_resp_data));
1853 if (cont_req_or_resp_data == NULL)
1854 return NULL;
1855
1856 cont_req_or_resp_data->rsp_type = rsp_type;
1857 switch (rsp_type) {
1858 case MAILIMAP_RESP_CONT_REQ:
1859 cont_req_or_resp_data->rsp_data.rsp_cont_req = rsp_cont_req;
1860 break;
1861 case MAILIMAP_RESP_RESP_DATA:
1862 cont_req_or_resp_data->rsp_data.rsp_resp_data = rsp_resp_data;
1863 break;
1864 }
1865
1866 return cont_req_or_resp_data;
1867}
1868
1869void
1870mailimap_cont_req_or_resp_data_free(struct mailimap_cont_req_or_resp_data *
1871 cont_req_or_resp_data)
1872{
1873 switch (cont_req_or_resp_data->rsp_type) {
1874 case MAILIMAP_RESP_CONT_REQ:
1875 if (cont_req_or_resp_data->rsp_data.rsp_cont_req != NULL)
1876 mailimap_continue_req_free(cont_req_or_resp_data->rsp_data.rsp_cont_req);
1877 break;
1878 case MAILIMAP_RESP_RESP_DATA:
1879 if (cont_req_or_resp_data->rsp_data.rsp_resp_data != NULL)
1880 mailimap_response_data_free(cont_req_or_resp_data->rsp_data.rsp_resp_data);
1881 break;
1882 }
1883 free(cont_req_or_resp_data);
1884}
1885
1886
1887
1888
1889struct mailimap_response *
1890mailimap_response_new(clist * rsp_cont_req_or_resp_data_list,
1891 struct mailimap_response_done * rsp_resp_done)
1892{
1893 struct mailimap_response * resp;
1894
1895 resp = malloc(sizeof(* resp));
1896 if (resp == NULL)
1897 return NULL;
1898
1899 resp->rsp_cont_req_or_resp_data_list = rsp_cont_req_or_resp_data_list;
1900 resp->rsp_resp_done = rsp_resp_done;
1901
1902 return resp;
1903}
1904
1905void
1906mailimap_response_free(struct mailimap_response * resp)
1907{
1908 if (resp->rsp_cont_req_or_resp_data_list != NULL) {
1909 clist_foreach(resp->rsp_cont_req_or_resp_data_list,
1910 (clist_func) mailimap_cont_req_or_resp_data_free, NULL);
1911 clist_free(resp->rsp_cont_req_or_resp_data_list);
1912 }
1913 mailimap_response_done_free(resp->rsp_resp_done);
1914 free(resp);
1915}
1916
1917
1918
1919struct mailimap_response_data *
1920mailimap_response_data_new(int rsp_type,
1921 struct mailimap_resp_cond_state * rsp_cond_state,
1922 struct mailimap_resp_cond_bye * rsp_bye,
1923 struct mailimap_mailbox_data * rsp_mailbox_data,
1924 struct mailimap_message_data * rsp_message_data,
1925 struct mailimap_capability_data * rsp_capability_data)
1926{
1927 struct mailimap_response_data * resp_data;
1928
1929 resp_data = malloc(sizeof(* resp_data));
1930 if (resp_data == NULL)
1931 return NULL;
1932 resp_data->rsp_type = rsp_type;
1933
1934 switch (rsp_type) {
1935 case MAILIMAP_RESP_DATA_TYPE_COND_STATE:
1936 resp_data->rsp_data.rsp_cond_state = rsp_cond_state;
1937 break;
1938 case MAILIMAP_RESP_DATA_TYPE_COND_BYE:
1939 resp_data->rsp_data.rsp_bye = rsp_bye;
1940 break;
1941 case MAILIMAP_RESP_DATA_TYPE_MAILBOX_DATA:
1942 resp_data->rsp_data.rsp_mailbox_data = rsp_mailbox_data;
1943 break;
1944 case MAILIMAP_RESP_DATA_TYPE_MESSAGE_DATA:
1945 resp_data->rsp_data.rsp_message_data = rsp_message_data;
1946 break;
1947 case MAILIMAP_RESP_DATA_TYPE_CAPABILITY_DATA:
1948 resp_data->rsp_data.rsp_capability_data = rsp_capability_data;
1949 break;
1950 }
1951
1952 return resp_data;
1953}
1954
1955void
1956mailimap_response_data_free(struct mailimap_response_data * resp_data)
1957{
1958 switch (resp_data->rsp_type) {
1959 case MAILIMAP_RESP_DATA_TYPE_COND_STATE:
1960 if (resp_data->rsp_data.rsp_cond_state != NULL)
1961 mailimap_resp_cond_state_free(resp_data->rsp_data.rsp_cond_state);
1962 break;
1963 case MAILIMAP_RESP_DATA_TYPE_COND_BYE:
1964 if (resp_data->rsp_data.rsp_bye != NULL)
1965 mailimap_resp_cond_bye_free(resp_data->rsp_data.rsp_bye);
1966 break;
1967 case MAILIMAP_RESP_DATA_TYPE_MAILBOX_DATA:
1968 if (resp_data->rsp_data.rsp_mailbox_data != NULL)
1969 mailimap_mailbox_data_free(resp_data->rsp_data.rsp_mailbox_data);
1970 break;
1971 case MAILIMAP_RESP_DATA_TYPE_MESSAGE_DATA:
1972 if (resp_data->rsp_data.rsp_message_data != NULL)
1973 mailimap_message_data_free(resp_data->rsp_data.rsp_message_data);
1974 break;
1975 case MAILIMAP_RESP_DATA_TYPE_CAPABILITY_DATA:
1976 if (resp_data->rsp_data.rsp_capability_data != NULL)
1977 mailimap_capability_data_free(resp_data->rsp_data.rsp_capability_data);
1978 break;
1979 }
1980 free(resp_data);
1981}
1982
1983
1984
1985struct mailimap_response_done *
1986mailimap_response_done_new(int rsp_type,
1987 struct mailimap_response_tagged * rsp_tagged,
1988 struct mailimap_response_fatal * rsp_fatal)
1989{
1990 struct mailimap_response_done * resp_done;
1991
1992 resp_done = malloc(sizeof(* resp_done));
1993 if (resp_done == NULL)
1994 return NULL;
1995
1996 resp_done->rsp_type = rsp_type;
1997 switch (rsp_type) {
1998 case MAILIMAP_RESP_DONE_TYPE_TAGGED:
1999 resp_done->rsp_data.rsp_tagged = rsp_tagged;
2000 break;
2001 case MAILIMAP_RESP_DONE_TYPE_FATAL:
2002 resp_done->rsp_data.rsp_fatal = rsp_fatal;
2003 break;
2004 }
2005
2006 return resp_done;
2007}
2008
2009void mailimap_response_done_free(struct mailimap_response_done *
2010 resp_done)
2011{
2012 switch (resp_done->rsp_type) {
2013 case MAILIMAP_RESP_DONE_TYPE_TAGGED:
2014 mailimap_response_tagged_free(resp_done->rsp_data.rsp_tagged);
2015 break;
2016 case MAILIMAP_RESP_DONE_TYPE_FATAL:
2017 mailimap_response_fatal_free(resp_done->rsp_data.rsp_fatal);
2018 break;
2019 }
2020 free(resp_done);
2021}
2022
2023struct mailimap_response_fatal *
2024mailimap_response_fatal_new(struct mailimap_resp_cond_bye * rsp_bye)
2025{
2026 struct mailimap_response_fatal * resp_fatal;
2027
2028 resp_fatal = malloc(sizeof(* resp_fatal));
2029 if (resp_fatal == NULL)
2030 return NULL;
2031
2032 resp_fatal->rsp_bye = rsp_bye;
2033
2034 return NULL;
2035}
2036
2037void mailimap_response_fatal_free(struct mailimap_response_fatal * resp_fatal)
2038{
2039 mailimap_resp_cond_bye_free(resp_fatal->rsp_bye);
2040 free(resp_fatal);
2041}
2042
2043struct mailimap_response_tagged *
2044mailimap_response_tagged_new(char * rsp_tag,
2045 struct mailimap_resp_cond_state * rsp_cond_state)
2046{
2047 struct mailimap_response_tagged * resp_tagged;
2048
2049 resp_tagged = malloc(sizeof(* resp_tagged));
2050 if (resp_tagged == NULL)
2051 return NULL;
2052
2053 resp_tagged->rsp_tag = rsp_tag;
2054 resp_tagged->rsp_cond_state = rsp_cond_state;
2055
2056 return resp_tagged;
2057}
2058
2059void
2060mailimap_response_tagged_free(struct mailimap_response_tagged * tagged)
2061{
2062 mailimap_tag_free(tagged->rsp_tag);
2063 mailimap_resp_cond_state_free(tagged->rsp_cond_state);
2064 free(tagged);
2065}
2066
2067
2068
2069struct mailimap_resp_cond_auth *
2070mailimap_resp_cond_auth_new(int rsp_type,
2071 struct mailimap_resp_text * rsp_text)
2072{
2073 struct mailimap_resp_cond_auth * cond_auth;
2074
2075 cond_auth = malloc(sizeof(* cond_auth));
2076 if (cond_auth == NULL)
2077 return NULL;
2078
2079 cond_auth->rsp_type = rsp_type;
2080 cond_auth->rsp_text = rsp_text;
2081
2082 return cond_auth;
2083}
2084
2085void
2086mailimap_resp_cond_auth_free(struct mailimap_resp_cond_auth * cond_auth)
2087{
2088 mailimap_resp_text_free(cond_auth->rsp_text);
2089 free(cond_auth);
2090}
2091
2092
2093
2094struct mailimap_resp_cond_bye *
2095mailimap_resp_cond_bye_new(struct mailimap_resp_text * rsp_text)
2096{
2097 struct mailimap_resp_cond_bye * cond_bye;
2098
2099 cond_bye = malloc(sizeof(* cond_bye));
2100 if (cond_bye == NULL)
2101 return NULL;
2102
2103 cond_bye->rsp_text = rsp_text;
2104
2105 return cond_bye;
2106}
2107
2108
2109void
2110mailimap_resp_cond_bye_free(struct mailimap_resp_cond_bye * cond_bye)
2111{
2112 mailimap_resp_text_free(cond_bye->rsp_text);
2113 free(cond_bye);
2114}
2115
2116
2117struct mailimap_resp_cond_state *
2118mailimap_resp_cond_state_new(int rsp_type,
2119 struct mailimap_resp_text * rsp_text)
2120{
2121 struct mailimap_resp_cond_state * cond_state;
2122
2123 cond_state = malloc(sizeof(* cond_state));
2124 if (cond_state == NULL)
2125 return NULL;
2126
2127 cond_state->rsp_type = rsp_type;
2128 cond_state->rsp_text = rsp_text;
2129
2130 return cond_state;
2131}
2132
2133void
2134mailimap_resp_cond_state_free(struct mailimap_resp_cond_state * cond_state)
2135{
2136 mailimap_resp_text_free(cond_state->rsp_text);
2137 free(cond_state);
2138}
2139
2140
2141struct mailimap_resp_text *
2142mailimap_resp_text_new(struct mailimap_resp_text_code * rsp_code,
2143 char * rsp_text)
2144{
2145 struct mailimap_resp_text * resp_text;
2146
2147 resp_text = malloc(sizeof(* resp_text));
2148 if (resp_text == NULL)
2149 return NULL;
2150
2151 resp_text->rsp_code = rsp_code;
2152 resp_text->rsp_text = rsp_text;
2153
2154 return resp_text;
2155}
2156
2157void mailimap_resp_text_free(struct mailimap_resp_text * resp_text)
2158{
2159 if (resp_text->rsp_code)
2160 mailimap_resp_text_code_free(resp_text->rsp_code);
2161 if (resp_text->rsp_text)
2162 mailimap_text_free(resp_text->rsp_text);
2163 free(resp_text);
2164}
2165
2166
2167
2168
2169struct mailimap_resp_text_code *
2170mailimap_resp_text_code_new(int rc_type, clist * rc_badcharset,
2171 struct mailimap_capability_data * rc_cap_data,
2172 clist * rc_perm_flags,
2173 uint32_t rc_uidnext, uint32_t rc_uidvalidity,
2174 uint32_t rc_first_unseen, char * rc_atom, char * rc_atom_value)
2175{
2176 struct mailimap_resp_text_code * resp_text_code;
2177
2178 resp_text_code = malloc(sizeof(* resp_text_code));
2179 if (resp_text_code == NULL)
2180 return NULL;
2181
2182 resp_text_code->rc_type = rc_type;
2183 switch (rc_type) {
2184 case MAILIMAP_RESP_TEXT_CODE_BADCHARSET:
2185 resp_text_code->rc_data.rc_badcharset = rc_badcharset;
2186 break;
2187 case MAILIMAP_RESP_TEXT_CODE_CAPABILITY_DATA:
2188 resp_text_code->rc_data.rc_cap_data = rc_cap_data;
2189 break;
2190 case MAILIMAP_RESP_TEXT_CODE_PERMANENTFLAGS:
2191 resp_text_code->rc_data.rc_perm_flags = rc_perm_flags;
2192 break;
2193 case MAILIMAP_RESP_TEXT_CODE_UIDNEXT:
2194 resp_text_code->rc_data.rc_uidnext = rc_uidnext;
2195 break;
2196 case MAILIMAP_RESP_TEXT_CODE_UIDVALIDITY:
2197 resp_text_code->rc_data.rc_uidvalidity = rc_uidvalidity;
2198 break;
2199 case MAILIMAP_RESP_TEXT_CODE_UNSEEN:
2200 resp_text_code->rc_data.rc_first_unseen = rc_first_unseen;
2201 break;
2202 case MAILIMAP_RESP_TEXT_CODE_OTHER:
2203 resp_text_code->rc_data.rc_atom.atom_name = rc_atom;
2204 resp_text_code->rc_data.rc_atom.atom_value = rc_atom_value;
2205 break;
2206 }
2207
2208 return resp_text_code;
2209}
2210
2211void
2212mailimap_resp_text_code_free(struct mailimap_resp_text_code * resp_text_code)
2213{
2214 switch (resp_text_code->rc_type) {
2215 case MAILIMAP_RESP_TEXT_CODE_BADCHARSET:
2216 if (resp_text_code->rc_data.rc_badcharset != NULL) {
2217 clist_foreach(resp_text_code->rc_data.rc_badcharset,
2218 (clist_func) mailimap_astring_free,
2219 NULL);
2220 clist_free(resp_text_code->rc_data.rc_badcharset);
2221 }
2222 break;
2223 case MAILIMAP_RESP_TEXT_CODE_CAPABILITY_DATA:
2224 if (resp_text_code->rc_data.rc_cap_data != NULL)
2225 mailimap_capability_data_free(resp_text_code->rc_data.rc_cap_data);
2226 break;
2227 case MAILIMAP_RESP_TEXT_CODE_PERMANENTFLAGS:
2228 if (resp_text_code->rc_data.rc_perm_flags != NULL) {
2229 clist_foreach(resp_text_code->rc_data.rc_perm_flags,
2230 (clist_func) mailimap_flag_perm_free, NULL);
2231 clist_free(resp_text_code->rc_data.rc_perm_flags);
2232 }
2233 break;
2234 case MAILIMAP_RESP_TEXT_CODE_OTHER:
2235 if (resp_text_code->rc_data.rc_atom.atom_name != NULL)
2236 mailimap_atom_free(resp_text_code->rc_data.rc_atom.atom_name);
2237 if (resp_text_code->rc_data.rc_atom.atom_value != NULL)
2238 mailimap_custom_string_free(resp_text_code->rc_data.rc_atom.atom_value);
2239 break;
2240 }
2241 free(resp_text_code);
2242}
2243
2244
2245struct mailimap_section *
2246mailimap_section_new(struct mailimap_section_spec * sec_spec)
2247{
2248 struct mailimap_section * section;
2249
2250 section = malloc(sizeof(* section));
2251 if (section == NULL)
2252 return NULL;
2253
2254 section->sec_spec = sec_spec;
2255
2256 return section;
2257}
2258
2259void mailimap_section_free(struct mailimap_section * section)
2260{
2261 if (section->sec_spec != NULL)
2262 mailimap_section_spec_free(section->sec_spec);
2263 free(section);
2264}
2265
2266
2267
2268struct mailimap_section_msgtext *
2269mailimap_section_msgtext_new(int sec_type,
2270 struct mailimap_header_list * sec_header_list)
2271{
2272 struct mailimap_section_msgtext * msgtext;
2273
2274 msgtext = malloc(sizeof(* msgtext));
2275 if (msgtext == NULL)
2276 return FALSE;
2277
2278 msgtext->sec_type = sec_type;
2279 msgtext->sec_header_list = sec_header_list;
2280
2281 return msgtext;
2282}
2283
2284void
2285mailimap_section_msgtext_free(struct mailimap_section_msgtext * msgtext)
2286{
2287 if (msgtext->sec_header_list != NULL)
2288 mailimap_header_list_free(msgtext->sec_header_list);
2289 free(msgtext);
2290}
2291
2292
2293struct mailimap_section_part *
2294mailimap_section_part_new(clist * sec_id)
2295{
2296 struct mailimap_section_part * section_part;
2297
2298 section_part = malloc(sizeof(* section_part));
2299 if (section_part == NULL)
2300 return NULL;
2301
2302 section_part->sec_id = sec_id;
2303
2304 return section_part;
2305}
2306
2307void
2308mailimap_section_part_free(struct mailimap_section_part * section_part)
2309{
2310 clist_foreach(section_part->sec_id,
2311 (clist_func) mailimap_number_alloc_free, NULL);
2312 clist_free(section_part->sec_id);
2313 free(section_part);
2314}
2315
2316
2317struct mailimap_section_spec *
2318mailimap_section_spec_new(int sec_type,
2319 struct mailimap_section_msgtext * sec_msgtext,
2320 struct mailimap_section_part * sec_part,
2321 struct mailimap_section_text * sec_text)
2322{
2323 struct mailimap_section_spec * section_spec;
2324
2325 section_spec = malloc(sizeof(* section_spec));
2326 if (section_spec == NULL)
2327 return NULL;
2328
2329 section_spec->sec_type = sec_type;
2330 switch (sec_type) {
2331 case MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT:
2332 section_spec->sec_data.sec_msgtext = sec_msgtext;
2333 break;
2334 case MAILIMAP_SECTION_SPEC_SECTION_PART:
2335 section_spec->sec_data.sec_part = sec_part;
2336 break;
2337 }
2338 section_spec->sec_text = sec_text;
2339
2340 return section_spec;
2341}
2342
2343void
2344mailimap_section_spec_free(struct mailimap_section_spec * section_spec)
2345{
2346 if (section_spec->sec_text)
2347 mailimap_section_text_free(section_spec->sec_text);
2348
2349 switch (section_spec->sec_type) {
2350 case MAILIMAP_SECTION_SPEC_SECTION_PART:
2351 if (section_spec->sec_data.sec_part != NULL)
2352 mailimap_section_part_free(section_spec->sec_data.sec_part);
2353 break;
2354 case MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT:
2355 /* handle case where it can be detached */
2356 if (section_spec->sec_data.sec_msgtext != NULL)
2357 mailimap_section_msgtext_free(section_spec->sec_data.sec_msgtext);
2358 break;
2359 }
2360 free(section_spec);
2361}
2362
2363
2364struct mailimap_section_text *
2365mailimap_section_text_new(int sec_type,
2366 struct mailimap_section_msgtext * sec_msgtext)
2367{
2368 struct mailimap_section_text * section_text;
2369
2370 section_text = malloc(sizeof(* section_text));
2371 if (section_text == NULL)
2372 return NULL;
2373
2374 section_text->sec_type = sec_type;
2375 section_text->sec_msgtext = sec_msgtext;
2376
2377 return section_text;
2378}
2379
2380void
2381mailimap_section_text_free(struct mailimap_section_text * section_text)
2382{
2383 if (section_text->sec_msgtext != NULL)
2384 mailimap_section_msgtext_free(section_text->sec_msgtext);
2385 free(section_text);
2386}
2387
2388
2389
2390
2391void
2392mailimap_string_free(char * str)
2393{
2394 mmap_string_unref(str);
2395}
2396
2397
2398
2399
2400
2401void mailimap_tag_free(char * tag)
2402{
2403 mailimap_custom_string_free(tag);
2404}
2405
2406
2407void mailimap_text_free(char * text)
2408{
2409 mailimap_custom_string_free(text);
2410}
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433/* ************************************************************************* */
2434/* ************************************************************************* */
2435/* ************************************************************************* */
2436/* ************************************************************************* */
2437/* ************************************************************************* */
2438/* ************************************************************************* */
2439
2440
2441
2442
2443
2444
2445/* sender only */
2446
2447
2448/* COPY FETCH SEARCH STORE */
2449/* set */
2450
2451struct mailimap_set_item *
2452mailimap_set_item_new(uint32_t set_first, uint32_t set_last)
2453{
2454 struct mailimap_set_item * item;
2455
2456 item = malloc(sizeof(* item));
2457 if (item == NULL)
2458 return NULL;
2459
2460 item->set_first = set_first;
2461 item->set_last = set_last;
2462
2463 return item;
2464}
2465
2466void mailimap_set_item_free(struct mailimap_set_item * set_item)
2467{
2468 free(set_item);
2469}
2470
2471struct mailimap_set * mailimap_set_new(clist * set_list)
2472{
2473 struct mailimap_set * set;
2474
2475 set = malloc(sizeof(* set));
2476 if (set == NULL)
2477 return NULL;
2478
2479 set->set_list = set_list;
2480
2481 return set;
2482}
2483
2484void mailimap_set_free(struct mailimap_set * set)
2485{
2486 clist_foreach(set->set_list, (clist_func) mailimap_set_item_free, NULL);
2487 clist_free(set->set_list);
2488 free(set);
2489}
2490
2491/* SEARCH with date key */
2492/* date */
2493
2494struct mailimap_date *
2495mailimap_date_new(int dt_day, int dt_month, int dt_year)
2496{
2497 struct mailimap_date * date;
2498
2499 date = malloc(sizeof(* date));
2500 if (date == NULL)
2501 return NULL;
2502
2503 date->dt_day = dt_day;
2504 date->dt_month = dt_month;
2505 date->dt_year = dt_year;
2506
2507 return date;
2508}
2509
2510void mailimap_date_free(struct mailimap_date * date)
2511{
2512 free(date);
2513}
2514
2515
2516
2517struct mailimap_fetch_att *
2518mailimap_fetch_att_new(int att_type, struct mailimap_section * att_section,
2519 uint32_t att_offset, uint32_t att_size)
2520{
2521 struct mailimap_fetch_att * fetch_att;
2522
2523 fetch_att = malloc(sizeof(* fetch_att));
2524 if (fetch_att == NULL)
2525 return NULL;
2526 fetch_att->att_type = att_type;
2527 fetch_att->att_section = att_section;
2528 fetch_att->att_offset = att_offset;
2529 fetch_att->att_size = att_size;
2530
2531 return fetch_att;
2532}
2533
2534void mailimap_fetch_att_free(struct mailimap_fetch_att * fetch_att)
2535{
2536 if (fetch_att->att_section != NULL)
2537 mailimap_section_free(fetch_att->att_section);
2538 free(fetch_att);
2539}
2540
2541
2542
2543struct mailimap_fetch_type *
2544mailimap_fetch_type_new(int ft_type,
2545 struct mailimap_fetch_att * ft_fetch_att,
2546 clist * ft_fetch_att_list)
2547{
2548 struct mailimap_fetch_type * fetch_type;
2549
2550 fetch_type = malloc(sizeof(* fetch_type));
2551 if (fetch_type == NULL)
2552 return NULL;
2553 fetch_type->ft_type = ft_type;
2554 switch (ft_type) {
2555 case MAILIMAP_FETCH_TYPE_FETCH_ATT:
2556 fetch_type->ft_data.ft_fetch_att = ft_fetch_att;
2557 break;
2558 case MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST:
2559 fetch_type->ft_data.ft_fetch_att_list = ft_fetch_att_list;
2560 break;
2561 }
2562
2563 return fetch_type;
2564}
2565
2566void mailimap_fetch_type_free(struct mailimap_fetch_type * fetch_type)
2567{
2568 switch (fetch_type->ft_type) {
2569 case MAILIMAP_FETCH_TYPE_FETCH_ATT:
2570 mailimap_fetch_att_free(fetch_type->ft_data.ft_fetch_att);
2571 break;
2572 case MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST:
2573 clist_foreach(fetch_type->ft_data.ft_fetch_att_list,
2574 (clist_func) mailimap_fetch_att_free, NULL);
2575 clist_free(fetch_type->ft_data.ft_fetch_att_list);
2576 break;
2577 }
2578 free(fetch_type);
2579}
2580
2581
2582
2583
2584struct mailimap_store_att_flags *
2585mailimap_store_att_flags_new(int fl_sign, int fl_silent,
2586 struct mailimap_flag_list * fl_flag_list)
2587{
2588 struct mailimap_store_att_flags * store_att_flags;
2589
2590 store_att_flags = malloc(sizeof(* store_att_flags));
2591 if (store_att_flags == NULL)
2592 return NULL;
2593
2594 store_att_flags->fl_sign = fl_sign;
2595 store_att_flags->fl_silent = fl_silent;
2596 store_att_flags->fl_flag_list = fl_flag_list;
2597
2598 return store_att_flags;
2599}
2600
2601void mailimap_store_att_flags_free(struct mailimap_store_att_flags *
2602 store_att_flags)
2603{
2604 mailimap_flag_list_free(store_att_flags->fl_flag_list);
2605 free(store_att_flags);
2606}
2607
2608
2609struct mailimap_search_key *
2610mailimap_search_key_new(int sk_type,
2611 char * sk_bcc, struct mailimap_date * sk_before, char * sk_body,
2612 char * sk_cc, char * sk_from, char * sk_keyword,
2613 struct mailimap_date * sk_on, struct mailimap_date * sk_since,
2614 char * sk_subject, char * sk_text, char * sk_to,
2615 char * sk_unkeyword, char * sk_header_name,
2616 char * sk_header_value, uint32_t sk_larger,
2617 struct mailimap_search_key * sk_not,
2618 struct mailimap_search_key * sk_or1,
2619 struct mailimap_search_key * sk_or2,
2620 struct mailimap_date * sk_sentbefore,
2621 struct mailimap_date * sk_senton,
2622 struct mailimap_date * sk_sentsince,
2623 uint32_t sk_smaller, struct mailimap_set * sk_uid,
2624 struct mailimap_set * sk_set, clist * sk_multiple)
2625{
2626 struct mailimap_search_key * key;
2627
2628 key = malloc(sizeof(* key));
2629 if (key == NULL)
2630 return NULL;
2631
2632 key->sk_type = sk_type;
2633 switch (sk_type) {
2634 case MAILIMAP_SEARCH_KEY_BCC:
2635 key->sk_data.sk_bcc = sk_bcc;
2636 break;
2637 case MAILIMAP_SEARCH_KEY_BEFORE:
2638 key->sk_data.sk_before = sk_before;
2639 break;
2640 case MAILIMAP_SEARCH_KEY_BODY:
2641 key->sk_data.sk_body = sk_body;
2642 break;
2643 case MAILIMAP_SEARCH_KEY_CC:
2644 key->sk_data.sk_cc = sk_cc;
2645 break;
2646 case MAILIMAP_SEARCH_KEY_FROM:
2647 key->sk_data.sk_from = sk_from;
2648 break;
2649 case MAILIMAP_SEARCH_KEY_KEYWORD:
2650 key->sk_data.sk_keyword = sk_keyword;
2651 break;
2652 case MAILIMAP_SEARCH_KEY_ON:
2653 key->sk_data.sk_on = sk_on;
2654 break;
2655 case MAILIMAP_SEARCH_KEY_SINCE:
2656 key->sk_data.sk_since = sk_since;
2657 break;
2658 case MAILIMAP_SEARCH_KEY_SUBJECT:
2659 key->sk_data.sk_subject = sk_subject;
2660 break;
2661 case MAILIMAP_SEARCH_KEY_TEXT:
2662 key->sk_data.sk_text = sk_text;
2663 break;
2664 case MAILIMAP_SEARCH_KEY_TO:
2665 key->sk_data.sk_to = sk_to;
2666 break;
2667 case MAILIMAP_SEARCH_KEY_UNKEYWORD:
2668 key->sk_data.sk_unkeyword = sk_unkeyword;
2669 break;
2670 case MAILIMAP_SEARCH_KEY_HEADER:
2671 key->sk_data.sk_header.sk_header_name = sk_header_name;
2672 key->sk_data.sk_header.sk_header_value = sk_header_value;
2673 break;
2674 case MAILIMAP_SEARCH_KEY_LARGER:
2675 key->sk_data.sk_larger = sk_larger;
2676 break;
2677 case MAILIMAP_SEARCH_KEY_NOT:
2678 key->sk_data.sk_not = sk_not;
2679 break;
2680 case MAILIMAP_SEARCH_KEY_OR:
2681 key->sk_data.sk_or.sk_or1 = sk_or1;
2682 key->sk_data.sk_or.sk_or2 = sk_or2;
2683 break;
2684 case MAILIMAP_SEARCH_KEY_SENTBEFORE:
2685 key->sk_data.sk_sentbefore = sk_sentbefore;
2686 break;
2687 case MAILIMAP_SEARCH_KEY_SENTON:
2688 key->sk_data.sk_senton = sk_senton;
2689 break;
2690 case MAILIMAP_SEARCH_KEY_SENTSINCE:
2691 key->sk_data.sk_sentsince = sk_sentsince;
2692 break;
2693 case MAILIMAP_SEARCH_KEY_SMALLER:
2694 key->sk_data.sk_smaller = sk_smaller;
2695 break;
2696 case MAILIMAP_SEARCH_KEY_UID:
2697 key->sk_data.sk_uid = sk_uid;
2698 break;
2699 case MAILIMAP_SEARCH_KEY_SET:
2700 key->sk_data.sk_set = sk_set;
2701 break;
2702 case MAILIMAP_SEARCH_KEY_MULTIPLE:
2703 key->sk_data.sk_multiple = sk_multiple;
2704 break;
2705 }
2706 return key;
2707}
2708
2709
2710void mailimap_search_key_free(struct mailimap_search_key * key)
2711{
2712 switch (key->sk_type) {
2713 case MAILIMAP_SEARCH_KEY_BCC:
2714 mailimap_astring_free(key->sk_data.sk_bcc);
2715 break;
2716 case MAILIMAP_SEARCH_KEY_BEFORE:
2717 mailimap_date_free(key->sk_data.sk_before);
2718 break;
2719 case MAILIMAP_SEARCH_KEY_BODY:
2720 mailimap_astring_free(key->sk_data.sk_body);
2721 break;
2722 case MAILIMAP_SEARCH_KEY_CC:
2723 mailimap_astring_free(key->sk_data.sk_cc);
2724 break;
2725 case MAILIMAP_SEARCH_KEY_FROM:
2726 mailimap_astring_free(key->sk_data.sk_from);
2727 break;
2728 case MAILIMAP_SEARCH_KEY_KEYWORD:
2729 mailimap_flag_keyword_free(key->sk_data.sk_keyword);
2730 break;
2731 case MAILIMAP_SEARCH_KEY_ON:
2732 mailimap_date_free(key->sk_data.sk_on);
2733 break;
2734 case MAILIMAP_SEARCH_KEY_SINCE:
2735 mailimap_date_free(key->sk_data.sk_since);
2736 break;
2737 case MAILIMAP_SEARCH_KEY_SUBJECT:
2738 mailimap_astring_free(key->sk_data.sk_subject);
2739 break;
2740 case MAILIMAP_SEARCH_KEY_TEXT:
2741 mailimap_astring_free(key->sk_data.sk_text);
2742 break;
2743 case MAILIMAP_SEARCH_KEY_TO:
2744 mailimap_astring_free(key->sk_data.sk_to);
2745 break;
2746 case MAILIMAP_SEARCH_KEY_UNKEYWORD:
2747 mailimap_flag_keyword_free(key->sk_data.sk_unkeyword);
2748 break;
2749 case MAILIMAP_SEARCH_KEY_HEADER:
2750 mailimap_header_fld_name_free(key->sk_data.sk_header.sk_header_name);
2751 mailimap_astring_free(key->sk_data.sk_header.sk_header_value);
2752 break;
2753 case MAILIMAP_SEARCH_KEY_NOT:
2754 mailimap_search_key_free(key->sk_data.sk_not);
2755 break;
2756 case MAILIMAP_SEARCH_KEY_OR:
2757 mailimap_search_key_free(key->sk_data.sk_or.sk_or1);
2758 mailimap_search_key_free(key->sk_data.sk_or.sk_or2);
2759 break;
2760 case MAILIMAP_SEARCH_KEY_SENTBEFORE:
2761 mailimap_date_free(key->sk_data.sk_sentbefore);
2762 break;
2763 case MAILIMAP_SEARCH_KEY_SENTON:
2764 mailimap_date_free(key->sk_data.sk_senton);
2765 break;
2766 case MAILIMAP_SEARCH_KEY_SENTSINCE:
2767 mailimap_date_free(key->sk_data.sk_sentsince);
2768 break;
2769 case MAILIMAP_SEARCH_KEY_UID:
2770 mailimap_set_free(key->sk_data.sk_uid);
2771 break;
2772 case MAILIMAP_SEARCH_KEY_SET:
2773 mailimap_set_free(key->sk_data.sk_set);
2774 break;
2775 case MAILIMAP_SEARCH_KEY_MULTIPLE:
2776 clist_foreach(key->sk_data.sk_multiple,
2777 (clist_func) mailimap_search_key_free, NULL);
2778 clist_free(key->sk_data.sk_multiple);
2779 break;
2780 }
2781
2782 free(key);
2783}
2784
2785
2786
2787
2788
2789
2790
2791
2792struct mailimap_status_att_list *
2793mailimap_status_att_list_new(clist * att_list)
2794{
2795 struct mailimap_status_att_list * status_att_list;
2796
2797 status_att_list = malloc(sizeof(* status_att_list));
2798 if (status_att_list == NULL)
2799 return NULL;
2800 status_att_list->att_list = att_list;
2801
2802 return status_att_list;
2803}
2804
2805void mailimap_status_att_list_free(struct mailimap_status_att_list *
2806 status_att_list)
2807{
2808 clist_foreach(status_att_list->att_list, (clist_func) free, NULL);
2809 clist_free(status_att_list->att_list);
2810 free(status_att_list);
2811}
2812
2813
2814
2815
2816/* main */
2817
2818
2819struct mailimap_selection_info *
2820mailimap_selection_info_new(void)
2821{
2822 struct mailimap_selection_info * sel_info;
2823
2824 sel_info = malloc(sizeof(* sel_info));
2825 if (sel_info == NULL)
2826 return NULL;
2827
2828 sel_info->sel_perm_flags = NULL;
2829 sel_info->sel_perm = MAILIMAP_MAILBOX_READWRITE;
2830 sel_info->sel_uidnext = 0;
2831 sel_info->sel_uidvalidity = 0;
2832 sel_info->sel_first_unseen = 0;
2833 sel_info->sel_flags = NULL;
2834 sel_info->sel_exists = 0;
2835 sel_info->sel_recent = 0;
2836 sel_info->sel_unseen = 0;
2837
2838 return sel_info;
2839}
2840
2841void
2842mailimap_selection_info_free(struct mailimap_selection_info * sel_info)
2843{
2844 if (sel_info->sel_perm_flags != NULL) {
2845 clist_foreach(sel_info->sel_perm_flags,
2846 (clist_func) mailimap_flag_perm_free, NULL);
2847 clist_free(sel_info->sel_perm_flags);
2848 }
2849 if (sel_info->sel_flags)
2850 mailimap_flag_list_free(sel_info->sel_flags);
2851
2852 free(sel_info);
2853}
2854
2855struct mailimap_connection_info *
2856mailimap_connection_info_new(void)
2857{
2858 struct mailimap_connection_info * conn_info;
2859
2860 conn_info = malloc(sizeof(* conn_info));
2861 if (conn_info == NULL)
2862 return NULL;
2863
2864 conn_info->imap_capability = NULL;
2865
2866 return conn_info;
2867}
2868
2869void
2870mailimap_connection_info_free(struct mailimap_connection_info * conn_info)
2871{
2872 if (conn_info->imap_capability != NULL)
2873 mailimap_capability_data_free(conn_info->imap_capability);
2874 free(conn_info);
2875}
2876
2877struct mailimap_response_info *
2878mailimap_response_info_new(void)
2879{
2880 struct mailimap_response_info * resp_info;
2881
2882 resp_info = malloc(sizeof(* resp_info));
2883 if (resp_info == NULL)
2884 goto err;
2885
2886 resp_info->rsp_alert = NULL;
2887 resp_info->rsp_parse = NULL;
2888 resp_info->rsp_badcharset = NULL;
2889 resp_info->rsp_trycreate = FALSE;
2890 resp_info->rsp_mailbox_list = clist_new();
2891 if (resp_info->rsp_mailbox_list == NULL)
2892 goto free;
2893 resp_info->rsp_mailbox_lsub = clist_new();
2894 if (resp_info->rsp_mailbox_lsub == NULL)
2895 goto free_mb_list;
2896 resp_info->rsp_search_result = clist_new();
2897 if (resp_info->rsp_search_result == NULL)
2898 goto free_mb_lsub;
2899 resp_info->rsp_status = NULL;
2900 resp_info->rsp_expunged = clist_new();
2901 if (resp_info->rsp_expunged == NULL)
2902 goto free_search_result;
2903 resp_info->rsp_fetch_list = clist_new();
2904 if (resp_info->rsp_fetch_list == NULL)
2905 goto free_expunged;
2906
2907 return resp_info;
2908
2909 free_expunged:
2910 clist_free(resp_info->rsp_expunged);
2911 free_search_result:
2912 clist_free(resp_info->rsp_search_result);
2913 free_mb_lsub:
2914 clist_free(resp_info->rsp_mailbox_lsub);
2915 free_mb_list:
2916 clist_free(resp_info->rsp_mailbox_list);
2917 free:
2918 free(resp_info);
2919 err:
2920 return NULL;
2921}
2922
2923void
2924mailimap_response_info_free(struct mailimap_response_info * resp_info)
2925{
2926 if (resp_info->rsp_alert != NULL)
2927 free(resp_info->rsp_alert);
2928 if (resp_info->rsp_parse != NULL)
2929 free(resp_info->rsp_parse);
2930 if (resp_info->rsp_badcharset != NULL) {
2931 clist_foreach(resp_info->rsp_badcharset,
2932 (clist_func) mailimap_astring_free, NULL);
2933 clist_free(resp_info->rsp_badcharset);
2934 }
2935 if (resp_info->rsp_mailbox_list != NULL) {
2936 clist_foreach(resp_info->rsp_mailbox_list,
2937 (clist_func) mailimap_mailbox_list_free, NULL);
2938 clist_free(resp_info->rsp_mailbox_list);
2939 }
2940 if (resp_info->rsp_mailbox_lsub != NULL) {
2941 clist_foreach(resp_info->rsp_mailbox_lsub,
2942 (clist_func) mailimap_mailbox_list_free, NULL);
2943 clist_free(resp_info->rsp_mailbox_lsub);
2944 }
2945 if (resp_info->rsp_search_result != NULL)
2946 mailimap_mailbox_data_search_free(resp_info->rsp_search_result);
2947 if (resp_info->rsp_status != NULL)
2948 mailimap_mailbox_data_status_free(resp_info->rsp_status);
2949 if (resp_info->rsp_expunged != NULL) {
2950 clist_foreach(resp_info->rsp_expunged,
2951 (clist_func) mailimap_number_alloc_free, NULL);
2952 clist_free(resp_info->rsp_expunged);
2953 }
2954 if (resp_info->rsp_fetch_list != NULL) {
2955 clist_foreach(resp_info->rsp_fetch_list,
2956 (clist_func) mailimap_msg_att_free, NULL);
2957 clist_free(resp_info->rsp_fetch_list);
2958 }
2959
2960 free(resp_info);
2961}
diff --git a/kmicromail/libetpan/imap/mailimap_types.h b/kmicromail/libetpan/imap/mailimap_types.h
new file mode 100644
index 0000000..2996b53
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_types.h
@@ -0,0 +1,3274 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36/*
37 IMAP4rev1 grammar
38
39 address = "(" addr-name SP addr-adl SP addr-mailbox SP
40 addr-host ")"
41
42 addr-adl = nstring
43 ; Holds route from [RFC-822] route-addr if
44 ; non-NIL
45
46 addr-host = nstring
47 ; NIL indicates [RFC-822] group syntax.
48 ; Otherwise, holds [RFC-822] domain name
49
50 addr-mailbox = nstring
51 ; NIL indicates end of [RFC-822] group; if
52 ; non-NIL and addr-host is NIL, holds
53 ; [RFC-822] group name.
54 ; Otherwise, holds [RFC-822] local-part
55 ; after removing [RFC-822] quoting
56
57
58
59 addr-name = nstring
60 ; If non-NIL, holds phrase from [RFC-822]
61 ; mailbox after removing [RFC-822] quoting
62
63 append = "APPEND" SP mailbox [SP flag-list] [SP date-time] SP
64 literal
65
66 astring = 1*ASTRING-CHAR / string
67
68 ASTRING-CHAR = ATOM-CHAR / resp-specials
69
70 atom = 1*ATOM-CHAR
71
72 ATOM-CHAR = <any CHAR except atom-specials>
73
74 atom-specials = "(" / ")" / "{" / SP / CTL / list-wildcards /
75 quoted-specials / resp-specials
76
77 authenticate = "AUTHENTICATE" SP auth-type *(CRLF base64)
78
79 auth-type = atom
80 ; Defined by [SASL]
81
82 base64 = *(4base64-char) [base64-terminal]
83
84 base64-char = ALPHA / DIGIT / "+" / "/"
85 ; Case-sensitive
86
87 base64-terminal = (2base64-char "==") / (3base64-char "=")
88
89 body = "(" (body-type-1part / body-type-mpart) ")"
90
91 body-extension = nstring / number /
92 "(" body-extension *(SP body-extension) ")"
93 ; Future expansion. Client implementations
94 ; MUST accept body-extension fields. Server
95 ; implementations MUST NOT generate
96 ; body-extension fields except as defined by
97 ; future standard or standards-track
98 ; revisions of this specification.
99
100 body-ext-1part = body-fld-md5 [SP body-fld-dsp [SP body-fld-lang
101 *(SP body-extension)]]
102 ; MUST NOT be returned on non-extensible
103 ; "BODY" fetch
104
105
106 body-ext-mpart = body-fld-param [SP body-fld-dsp [SP body-fld-lang
107 *(SP body-extension)]]
108 ; MUST NOT be returned on non-extensible
109 ; "BODY" fetch
110
111 body-fields = body-fld-param SP body-fld-id SP body-fld-desc SP
112 body-fld-enc SP body-fld-octets
113
114 body-fld-desc = nstring
115
116 body-fld-dsp = "(" string SP body-fld-param ")" / nil
117
118 body-fld-enc = (DQUOTE ("7BIT" / "8BIT" / "BINARY" / "BASE64"/
119 "QUOTED-PRINTABLE") DQUOTE) / string
120
121 body-fld-id = nstring
122
123 body-fld-lang = nstring / "(" string *(SP string) ")"
124
125 body-fld-lines = number
126
127 body-fld-md5 = nstring
128
129 body-fld-octets = number
130
131 body-fld-param = "(" string SP string *(SP string SP string) ")" / nil
132
133 body-type-1part = (body-type-basic / body-type-msg / body-type-text)
134 [SP body-ext-1part]
135
136 body-type-basic = media-basic SP body-fields
137 ; MESSAGE subtype MUST NOT be "RFC822"
138
139 body-type-mpart = 1*body SP media-subtype
140 [SP body-ext-mpart]
141
142 body-type-msg = media-message SP body-fields SP envelope
143 SP body SP body-fld-lines
144
145 body-type-text = media-text SP body-fields SP body-fld-lines
146
147 capability = ("AUTH=" auth-type) / atom
148 ; New capabilities MUST begin with "X" or be
149 ; registered with IANA as standard or
150 ; standards-track
151
152
153 capability-data = "CAPABILITY" *(SP capability) SP "IMAP4rev1"
154 *(SP capability)
155 ; IMAP4rev1 servers which offer RFC 1730
156 ; compatibility MUST list "IMAP4" as the first
157 ; capability.
158
159 CHAR8 = %x01-ff
160 ; any OCTET except NUL, %x00
161
162 command = tag SP (command-any / command-auth / command-nonauth /
163 command-select) CRLF
164 ; Modal based on state
165
166 command-any = "CAPABILITY" / "LOGOUT" / "NOOP" / x-command
167 ; Valid in all states
168
169 command-auth = append / create / delete / examine / list / lsub /
170 rename / select / status / subscribe / unsubscribe
171 ; Valid only in Authenticated or Selected state
172
173 command-nonauth = login / authenticate
174 ; Valid only when in Not Authenticated state
175
176 command-select = "CHECK" / "CLOSE" / "EXPUNGE" / copy / fetch / store /
177 uid / search
178 ; Valid only when in Selected state
179
180 continue-req = "+" SP (resp-text / base64) CRLF
181
182 copy = "COPY" SP set SP mailbox
183
184 create = "CREATE" SP mailbox
185 ; Use of INBOX gives a NO error
186
187 date = date-text / DQUOTE date-text DQUOTE
188
189 date-day = 1*2DIGIT
190 ; Day of month
191
192 date-day-fixed = (SP DIGIT) / 2DIGIT
193 ; Fixed-format version of date-day
194
195 date-month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" /
196 "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
197
198 date-text = date-day "-" date-month "-" date-year
199
200 date-year = 4DIGIT
201
202 date-time = DQUOTE date-day-fixed "-" date-month "-" date-year
203 SP time SP zone DQUOTE
204
205 delete = "DELETE" SP mailbox
206 ; Use of INBOX gives a NO error
207
208 digit-nz = %x31-39
209 ; 1-9
210
211 envelope = "(" env-date SP env-subject SP env-from SP env-sender SP
212 env-reply-to SP env-to SP env-cc SP env-bcc SP
213 env-in-reply-to SP env-message-id ")"
214
215 env-bcc = "(" 1*address ")" / nil
216
217 env-cc = "(" 1*address ")" / nil
218
219 env-date = nstring
220
221 env-from = "(" 1*address ")" / nil
222
223 env-in-reply-to = nstring
224
225 env-message-id = nstring
226
227 env-reply-to = "(" 1*address ")" / nil
228
229 env-sender = "(" 1*address ")" / nil
230
231 env-subject = nstring
232
233 env-to = "(" 1*address ")" / nil
234
235 examine = "EXAMINE" SP mailbox
236
237 fetch = "FETCH" SP set SP ("ALL" / "FULL" / "FAST" / fetch-att /
238 "(" fetch-att *(SP fetch-att) ")")
239
240 fetch-att = "ENVELOPE" / "FLAGS" / "INTERNALDATE" /
241 "RFC822" [".HEADER" / ".SIZE" / ".TEXT"] /
242 "BODY" ["STRUCTURE"] / "UID" /
243 "BODY" [".PEEK"] section ["<" number "." nz-number ">"]
244
245 flag = "\Answered" / "\Flagged" / "\Deleted" /
246 "\Seen" / "\Draft" / flag-keyword / flag-extension
247 ; Does not include "\Recent"
248
249 flag-extension = "\" atom
250 ; Future expansion. Client implementations
251 ; MUST accept flag-extension flags. Server
252 ; implementations MUST NOT generate
253 ; flag-extension flags except as defined by
254 ; future standard or standards-track
255 ; revisions of this specification.
256
257 flag-fetch = flag / "\Recent"
258
259 flag-keyword = atom
260
261 flag-list = "(" [flag *(SP flag)] ")"
262
263 flag-perm = flag / "\*"
264
265 greeting = "*" SP (resp-cond-auth / resp-cond-bye) CRLF
266
267 header-fld-name = astring
268
269 header-list = "(" header-fld-name *(SP header-fld-name) ")"
270
271 list = "LIST" SP mailbox SP list-mailbox
272
273 list-mailbox = 1*list-char / string
274
275 list-char = ATOM-CHAR / list-wildcards / resp-specials
276
277 list-wildcards = "%" / "*"
278
279 literal = "{" number "}" CRLF *CHAR8
280 ; Number represents the number of CHAR8s
281
282 login = "LOGIN" SP userid SP password
283
284 lsub = "LSUB" SP mailbox SP list-mailbox
285
286 mailbox = "INBOX" / astring
287 ; INBOX is case-insensitive. All case variants of
288 ; INBOX (e.g. "iNbOx") MUST be interpreted as INBOX
289 ; not as an astring. An astring which consists of
290 ; the case-insensitive sequence "I" "N" "B" "O" "X"
291 ; is considered to be INBOX and not an astring.
292 ; Refer to section 5.1 for further
293 ; semantic details of mailbox names.
294
295 mailbox-data = "FLAGS" SP flag-list / "LIST" SP mailbox-list /
296 "LSUB" SP mailbox-list / "SEARCH" *(SP nz-number) /
297 "STATUS" SP mailbox SP "("
298 [status-att SP number *(SP status-att SP number)] ")" /
299 number SP "EXISTS" / number SP "RECENT"
300
301 mailbox-list = "(" [mbx-list-flags] ")" SP
302 (DQUOTE QUOTED-CHAR DQUOTE / nil) SP mailbox
303
304 mbx-list-flags = *(mbx-list-oflag SP) mbx-list-sflag
305 *(SP mbx-list-oflag) /
306 mbx-list-oflag *(SP mbx-list-oflag)
307
308 mbx-list-oflag = "\Noinferiors" / flag-extension
309 ; Other flags; multiple possible per LIST response
310
311 mbx-list-sflag = "\Noselect" / "\Marked" / "\Unmarked"
312 ; Selectability flags; only one per LIST response
313
314 media-basic = ((DQUOTE ("APPLICATION" / "AUDIO" / "IMAGE" / "MESSAGE" /
315 "VIDEO") DQUOTE) / string) SP media-subtype
316 ; Defined in [MIME-IMT]
317
318 media-message = DQUOTE "MESSAGE" DQUOTE SP DQUOTE "RFC822" DQUOTE
319 ; Defined in [MIME-IMT]
320
321 media-subtype = string
322 ; Defined in [MIME-IMT]
323
324 media-text = DQUOTE "TEXT" DQUOTE SP media-subtype
325 ; Defined in [MIME-IMT]
326
327 message-data = nz-number SP ("EXPUNGE" / ("FETCH" SP msg-att))
328
329 msg-att = "(" (msg-att-dynamic / msg-att-static)
330 *(SP (msg-att-dynamic / msg-att-static)) ")"
331
332 msg-att-dynamic = "FLAGS" SP "(" [flag-fetch *(SP flag-fetch)] ")"
333 ; MAY change for a message
334
335 msg-att-static = "ENVELOPE" SP envelope / "INTERNALDATE" SP date-time /
336 "RFC822" [".HEADER" / ".TEXT"] SP nstring /
337 "RFC822.SIZE" SP number / "BODY" ["STRUCTURE"] SP body /
338 "BODY" section ["<" number ">"] SP nstring /
339 "UID" SP uniqueid
340 ; MUST NOT change for a message
341
342 nil = "NIL"
343
344 nstring = string / nil
345
346 number = 1*DIGIT
347 ; Unsigned 32-bit integer
348 ; (0 <= n < 4,294,967,296)
349
350 nz-number = digit-nz *DIGIT
351 ; Non-zero unsigned 32-bit integer
352 ; (0 < n < 4,294,967,296)
353
354 password = astring
355
356 quoted = DQUOTE *QUOTED-CHAR DQUOTE
357
358 QUOTED-CHAR = <any TEXT-CHAR except quoted-specials> /
359 "\" quoted-specials
360
361 quoted-specials = DQUOTE / "\"
362
363 rename = "RENAME" SP mailbox SP mailbox
364 ; Use of INBOX as a destination gives a NO error
365
366 response = *(continue-req / response-data) response-done
367
368 response-data = "*" SP (resp-cond-state / resp-cond-bye /
369 mailbox-data / message-data / capability-data) CRLF
370
371 response-done = response-tagged / response-fatal
372
373 response-fatal = "*" SP resp-cond-bye CRLF
374 ; Server closes connection immediately
375
376 response-tagged = tag SP resp-cond-state CRLF
377
378 resp-cond-auth = ("OK" / "PREAUTH") SP resp-text
379 ; Authentication condition
380
381 resp-cond-bye = "BYE" SP resp-text
382
383 resp-cond-state = ("OK" / "NO" / "BAD") SP resp-text
384 ; Status condition
385
386 resp-specials = "]"
387
388 resp-text = ["[" resp-text-code "]" SP] text
389
390 resp-text-code = "ALERT" /
391 "BADCHARSET" [SP "(" astring *(SP astring) ")" ] /
392 capability-data / "PARSE" /
393 "PERMANENTFLAGS" SP "(" [flag-perm *(SP flag-perm)] ")" /
394 "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
395 "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
396 "UNSEEN" SP nz-number /
397 atom [SP 1*<any TEXT-CHAR except "]">]
398
399 search = "SEARCH" [SP "CHARSET" SP astring] 1*(SP search-key)
400 ; CHARSET argument to MUST be registered with IANA
401
402 search-key = "ALL" / "ANSWERED" / "BCC" SP astring /
403 "BEFORE" SP date / "BODY" SP astring /
404 "CC" SP astring / "DELETED" / "FLAGGED" /
405 "FROM" SP astring / "KEYWORD" SP flag-keyword / "NEW" /
406 "OLD" / "ON" SP date / "RECENT" / "SEEN" /
407 "SINCE" SP date / "SUBJECT" SP astring /
408 "TEXT" SP astring / "TO" SP astring /
409 "UNANSWERED" / "UNDELETED" / "UNFLAGGED" /
410 "UNKEYWORD" SP flag-keyword / "UNSEEN" /
411 ; Above this line were in [IMAP2]
412 "DRAFT" / "HEADER" SP header-fld-name SP astring /
413 "LARGER" SP number / "NOT" SP search-key /
414 "OR" SP search-key SP search-key /
415 "SENTBEFORE" SP date / "SENTON" SP date /
416 "SENTSINCE" SP date / "SMALLER" SP number /
417 "UID" SP set / "UNDRAFT" / set /
418 "(" search-key *(SP search-key) ")"
419
420 section = "[" [section-spec] "]"
421
422 section-msgtext = "HEADER" / "HEADER.FIELDS" [".NOT"] SP header-list /
423 "TEXT"
424 ; top-level or MESSAGE/RFC822 part
425
426 section-part = nz-number *("." nz-number)
427 ; body part nesting
428
429 section-spec = section-msgtext / (section-part ["." section-text])
430
431 section-text = section-msgtext / "MIME"
432 ; text other than actual body part (headers, etc.)
433
434 select = "SELECT" SP mailbox
435
436 sequence-num = nz-number / "*"
437 ; * is the largest number in use. For message
438 ; sequence numbers, it is the number of messages
439 ; in the mailbox. For unique identifiers, it is
440 ; the unique identifier of the last message in
441 ; the mailbox.
442
443 set = sequence-num / (sequence-num ":" sequence-num) /
444 (set "," set)
445 ; Identifies a set of messages. For message
446 ; sequence numbers, these are consecutive
447 ; numbers from 1 to the number of messages in
448 ; the mailbox
449 ; Comma delimits individual numbers, colon
450 ; delimits between two numbers inclusive.
451 ; Example: 2,4:7,9,12:* is 2,4,5,6,7,9,12,13,
452 ; 14,15 for a mailbox with 15 messages.
453
454
455 status = "STATUS" SP mailbox SP "(" status-att *(SP status-att) ")"
456
457 status-att = "MESSAGES" / "RECENT" / "UIDNEXT" / "UIDVALIDITY" /
458 "UNSEEN"
459
460 store = "STORE" SP set SP store-att-flags
461
462 store-att-flags = (["+" / "-"] "FLAGS" [".SILENT"]) SP
463 (flag-list / (flag *(SP flag)))
464
465 string = quoted / literal
466
467 subscribe = "SUBSCRIBE" SP mailbox
468
469 tag = 1*<any ASTRING-CHAR except "+">
470
471 text = 1*TEXT-CHAR
472
473 TEXT-CHAR = <any CHAR except CR and LF>
474
475 time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
476 ; Hours minutes seconds
477
478 uid = "UID" SP (copy / fetch / search / store)
479 ; Unique identifiers used instead of message
480 ; sequence numbers
481
482 uniqueid = nz-number
483 ; Strictly ascending
484
485 unsubscribe = "UNSUBSCRIBE" SP mailbox
486
487 userid = astring
488
489 x-command = "X" atom <experimental command arguments>
490
491 zone = ("+" / "-") 4DIGIT
492 ; Signed four-digit value of hhmm representing
493 ; hours and minutes east of Greenwich (that is,
494 ; the amount that the given time differs from
495 ; Universal Time). Subtracting the timezone
496 ; from the given time will give the UT form.
497 ; The Universal Time zone is "+0000".
498*/
499
500
501#ifndef MAILIMAP_TYPES_H
502
503#define MAILIMAP_TYPES_H
504
505#ifdef __cplusplus
506extern "C" {
507#endif
508
509#include <inttypes.h>
510#include <libetpan/mailstream.h>
511#include <libetpan/clist.h>
512
513
514/*
515 IMPORTANT NOTE:
516
517 All allocation functions will take as argument allocated data
518 and will store these data in the structure they will allocate.
519 Data should be persistant during all the use of the structure
520 and will be freed by the free function of the structure
521
522 allocation functions will return NULL on failure
523*/
524
525
526/*
527 mailimap_address represents a mail address
528
529 - personal_name is the name to display in an address
530 '"name"' in '"name" <address@domain>', should be allocated
531 with a malloc()
532
533 - source_route is the source-route information in the
534 mail address (RFC 822), should be allocated with a malloc()
535
536 - mailbox_name is the name of the mailbox 'address' in
537 '"name" <address@domain>', should be allocated with a malloc()
538
539 - host_name is the name of the host 'domain' in
540 '"name" <address@domain>', should be allocated with a malloc()
541
542 if mailbox_name is not NULL and host_name is NULL, this is the name
543 of a group, the next addresses in the list are elements of the group
544 until we reach an address with a NULL mailbox_name.
545*/
546
547struct mailimap_address {
548 char * ad_personal_name; /* can be NULL */
549 char * ad_source_route; /* can be NULL */
550 char * ad_mailbox_name; /* can be NULL */
551 char * ad_host_name; /* can be NULL */
552};
553
554
555struct mailimap_address *
556mailimap_address_new(char * ad_personal_name, char * ad_source_route,
557 char * ad_mailbox_name, char * ad_host_name);
558
559void mailimap_address_free(struct mailimap_address * addr);
560
561
562/* this is the type of MIME body parsed by IMAP server */
563
564enum {
565 MAILIMAP_BODY_ERROR,
566 MAILIMAP_BODY_1PART, /* single part */
567 MAILIMAP_BODY_MPART, /* multi-part */
568};
569
570/*
571 mailimap_body represent a MIME body parsed by IMAP server
572
573 - type is the type of the MIME part (single part or multipart)
574
575 - body_1part is defined if this is a single part
576
577 - body_mpart is defined if this is a multipart
578*/
579
580struct mailimap_body {
581 int bd_type;
582 /* can be MAILIMAP_BODY_1PART or MAILIMAP_BODY_MPART */
583 union {
584 struct mailimap_body_type_1part * bd_body_1part; /* can be NULL */
585 struct mailimap_body_type_mpart * bd_body_mpart; /* can be NULL */
586 } bd_data;
587};
588
589
590struct mailimap_body *
591mailimap_body_new(int bd_type,
592 struct mailimap_body_type_1part * bd_body_1part,
593 struct mailimap_body_type_mpart * bd_body_mpart);
594
595void mailimap_body_free(struct mailimap_body * body);
596
597
598
599/*
600 this is the type of MIME body extension
601*/
602
603enum {
604 MAILIMAP_BODY_EXTENSION_ERROR,
605 MAILIMAP_BODY_EXTENSION_NSTRING, /* string */
606 MAILIMAP_BODY_EXTENSION_NUMBER, /* number */
607 MAILIMAP_BODY_EXTENSION_LIST, /* list of
608 (struct mailimap_body_extension *) */
609};
610
611/*
612 mailimap_body_extension is a future extension header field value
613
614 - type is the type of the body extension (string, number or
615 list of extension)
616
617 - nstring is a string value if the type is string
618
619 - number is a integer value if the type is number
620
621 - list is a list of body extension if the type is a list
622*/
623
624struct mailimap_body_extension {
625 int ext_type;
626 /*
627 can be MAILIMAP_BODY_EXTENSION_NSTRING, MAILIMAP_BODY_EXTENSION_NUMBER
628 or MAILIMAP_BODY_EXTENSION_LIST
629 */
630 union {
631 char * ext_nstring; /* can be NULL */
632 uint32_t ext_number;
633 clist * ext_body_extension_list;
634 /* list of (struct mailimap_body_extension *) */
635 /* can be NULL */
636 } ext_data;
637};
638
639struct mailimap_body_extension *
640mailimap_body_extension_new(int ext_type, char * ext_nstring,
641 uint32_t ext_number,
642 clist * ext_body_extension_list);
643
644void mailimap_body_extension_free(struct mailimap_body_extension * be);
645
646
647/*
648 mailimap_body_ext_1part is the extended result part of a single part
649 bodystructure.
650
651 - body_md5 is the value of the Content-MD5 header field, should be
652 allocated with malloc()
653
654 - body_disposition is the value of the Content-Disposition header field
655
656 - body_language is the value of the Content-Language header field
657
658 - body_extension_list is the list of extension fields value.
659*/
660
661struct mailimap_body_ext_1part {
662 char * bd_md5; /* != NULL */
663 struct mailimap_body_fld_dsp * bd_disposition; /* can be NULL */
664 struct mailimap_body_fld_lang * bd_language; /* can be NULL */
665
666 clist * bd_extension_list; /* list of (struct mailimap_body_extension *) */
667 /* can be NULL */
668};
669
670struct mailimap_body_ext_1part *
671mailimap_body_ext_1part_new(char * bd_md5,
672 struct mailimap_body_fld_dsp * bd_disposition,
673 struct mailimap_body_fld_lang * bd_language,
674 clist * bd_extension_list);
675
676
677void
678mailimap_body_ext_1part_free(struct mailimap_body_ext_1part * body_ext_1part);
679
680
681/*
682 mailimap_body_ext_mpart is the extended result part of a multipart
683 bodystructure.
684
685 - body_parameter is the list of parameters of Content-Type header field
686
687 - body_disposition is the value of Content-Disposition header field
688
689 - body_language is the value of Content-Language header field
690
691 - body_extension_list is the list of extension fields value.
692*/
693
694struct mailimap_body_ext_mpart {
695 struct mailimap_body_fld_param * bd_parameter; /* != NULL */
696 struct mailimap_body_fld_dsp * bd_disposition; /* can be NULL */
697 struct mailimap_body_fld_lang * bd_language; /* can be NULL */
698 clist * bd_extension_list; /* list of (struct mailimap_body_extension *) */
699 /* can be NULL */
700};
701
702struct mailimap_body_ext_mpart *
703mailimap_body_ext_mpart_new(struct mailimap_body_fld_param * bd_parameter,
704 struct mailimap_body_fld_dsp * bd_disposition,
705 struct mailimap_body_fld_lang * bd_language,
706 clist * bd_extension_list);
707
708void
709mailimap_body_ext_mpart_free(struct mailimap_body_ext_mpart * body_ext_mpart);
710
711
712/*
713 mailimap_body_fields is the MIME fields of a MIME part.
714
715 - body_parameter is the list of parameters of Content-Type header field
716
717 - body_id is the value of Content-ID header field, should be allocated
718 with malloc()
719
720 - body_description is the value of Content-Description header field,
721 should be allocated with malloc()
722
723 - body_encoding is the value of Content-Transfer-Encoding header field
724
725 - body_disposition is the value of Content-Disposition header field
726
727 - body_size is the size of the MIME part
728*/
729
730struct mailimap_body_fields {
731 struct mailimap_body_fld_param * bd_parameter; /* != NULL */
732 char * bd_id; /* can be NULL */
733 char * bd_description; /* can be NULL */
734 struct mailimap_body_fld_enc * bd_encoding; /* != NULL */
735 uint32_t bd_size;
736};
737
738struct mailimap_body_fields *
739mailimap_body_fields_new(struct mailimap_body_fld_param * bd_parameter,
740 char * bd_id,
741 char * bd_description,
742 struct mailimap_body_fld_enc * bd_encoding,
743 uint32_t bd_size);
744
745void
746mailimap_body_fields_free(struct mailimap_body_fields * body_fields);
747
748
749
750/*
751 mailimap_body_fld_dsp is the parsed value of the Content-Disposition field
752
753 - disposition_type is the type of Content-Disposition
754 (usually attachment or inline), should be allocated with malloc()
755
756 - attributes is the list of Content-Disposition attributes
757*/
758
759struct mailimap_body_fld_dsp {
760 char * dsp_type; /* != NULL */
761 struct mailimap_body_fld_param * dsp_attributes; /* != NULL */
762};
763
764struct mailimap_body_fld_dsp *
765mailimap_body_fld_dsp_new(char * dsp_type,
766 struct mailimap_body_fld_param * dsp_attributes);
767
768void mailimap_body_fld_dsp_free(struct mailimap_body_fld_dsp * bfd);
769
770
771
772/* these are the different parsed values for Content-Transfer-Encoding */
773
774enum {
775 MAILIMAP_BODY_FLD_ENC_7BIT, /* 7bit */
776 MAILIMAP_BODY_FLD_ENC_8BIT, /* 8bit */
777 MAILIMAP_BODY_FLD_ENC_BINARY, /* binary */
778 MAILIMAP_BODY_FLD_ENC_BASE64, /* base64 */
779 MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE, /* quoted-printable */
780 MAILIMAP_BODY_FLD_ENC_OTHER, /* other */
781};
782
783/*
784 mailimap_body_fld_enc is a parsed value for Content-Transfer-Encoding
785
786 - type is the kind of Content-Transfer-Encoding, this can be
787 MAILIMAP_BODY_FLD_ENC_7BIT, MAILIMAP_BODY_FLD_ENC_8BIT,
788 MAILIMAP_BODY_FLD_ENC_BINARY, MAILIMAP_BODY_FLD_ENC_BASE64,
789 MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE or MAILIMAP_BODY_FLD_ENC_OTHER
790
791 - in case of MAILIMAP_BODY_FLD_ENC_OTHER, this value is defined,
792 should be allocated with malloc()
793*/
794
795struct mailimap_body_fld_enc {
796 int enc_type;
797 char * enc_value; /* can be NULL */
798};
799
800struct mailimap_body_fld_enc *
801mailimap_body_fld_enc_new(int enc_type, char * enc_value);
802
803void mailimap_body_fld_enc_free(struct mailimap_body_fld_enc * bfe);
804
805
806/* this is the type of Content-Language header field value */
807
808enum {
809 MAILIMAP_BODY_FLD_LANG_ERROR, /* error parse */
810 MAILIMAP_BODY_FLD_LANG_SINGLE, /* single value */
811 MAILIMAP_BODY_FLD_LANG_LIST /* list of values */
812};
813
814/*
815 mailimap_body_fld_lang is the parsed value of the Content-Language field
816
817 - type is the type of content, this can be MAILIMAP_BODY_FLD_LANG_SINGLE
818 if this is a single value or MAILIMAP_BODY_FLD_LANG_LIST if there are
819 several values
820
821 - single is the single value if the type is MAILIMAP_BODY_FLD_LANG_SINGLE,
822 should be allocated with malloc()
823
824 - list is the list of value if the type is MAILIMAP_BODY_FLD_LANG_LIST,
825 all elements of the list should be allocated with malloc()
826*/
827
828struct mailimap_body_fld_lang {
829 int lg_type;
830 union {
831 char * lg_single; /* can be NULL */
832 clist * lg_list; /* list of string (char *), can be NULL */
833 } lg_data;
834};
835
836struct mailimap_body_fld_lang *
837mailimap_body_fld_lang_new(int lg_type, char * lg_single, clist * lg_list);
838
839void
840mailimap_body_fld_lang_free(struct mailimap_body_fld_lang * fld_lang);
841
842
843
844/*
845 mailimap_single_body_fld_param is a body field parameter
846
847 - name is the name of the parameter, should be allocated with malloc()
848
849 - value is the value of the parameter, should be allocated with malloc()
850*/
851
852struct mailimap_single_body_fld_param {
853 char * pa_name; /* != NULL */
854 char * pa_value; /* != NULL */
855};
856
857struct mailimap_single_body_fld_param *
858mailimap_single_body_fld_param_new(char * pa_name, char * pa_value);
859
860void
861mailimap_single_body_fld_param_free(struct mailimap_single_body_fld_param * p);
862
863
864/*
865 mailmap_body_fld_param is a list of parameters
866
867 - list is the list of parameters.
868*/
869
870struct mailimap_body_fld_param {
871 clist * pa_list; /* list of (struct mailimap_single_body_fld_param *) */
872 /* != NULL */
873};
874
875struct mailimap_body_fld_param *
876mailimap_body_fld_param_new(clist * pa_list);
877
878void
879mailimap_body_fld_param_free(struct mailimap_body_fld_param * fld_param);
880
881
882/*
883 this is the kind of single part: a text part
884 (when Content-Type is text/xxx), a message part (when Content-Type is
885 message/rfc2822) or a basic part (others than multpart/xxx)
886*/
887
888enum {
889 MAILIMAP_BODY_TYPE_1PART_ERROR, /* parse error */
890 MAILIMAP_BODY_TYPE_1PART_BASIC, /* others then multipart/xxx */
891 MAILIMAP_BODY_TYPE_1PART_MSG, /* message/rfc2822 */
892 MAILIMAP_BODY_TYPE_1PART_TEXT /* text/xxx */
893};
894
895
896/*
897 mailimap_body_type_1part is
898
899 - type is the kind of single part, this can be
900 MAILIMAP_BODY_TYPE_1PART_BASIC, MAILIMAP_BODY_TYPE_1PART_MSG or
901 MAILIMAP_BODY_TYPE_1PART_TEXT.
902
903 - body_type_basic is the basic part when type is
904 MAILIMAP_BODY_TYPE_1PART_BASIC
905
906 - body_type_msg is the message part when type is
907 MAILIMAP_BODY_TYPE_1PART_MSG
908
909 - body_type_text is the text part when type is
910 MAILIMAP_BODY_TYPE_1PART_TEXT
911*/
912
913struct mailimap_body_type_1part {
914 int bd_type;
915 union {
916 struct mailimap_body_type_basic * bd_type_basic; /* can be NULL */
917 struct mailimap_body_type_msg * bd_type_msg; /* can be NULL */
918 struct mailimap_body_type_text * bd_type_text; /* can be NULL */
919 } bd_data;
920 struct mailimap_body_ext_1part * bd_ext_1part; /* can be NULL */
921};
922
923struct mailimap_body_type_1part *
924mailimap_body_type_1part_new(int bd_type,
925 struct mailimap_body_type_basic * bd_type_basic,
926 struct mailimap_body_type_msg * bd_type_msg,
927 struct mailimap_body_type_text * bd_type_text,
928 struct mailimap_body_ext_1part * bd_ext_1part);
929
930void
931mailimap_body_type_1part_free(struct mailimap_body_type_1part * bt1p);
932
933
934
935/*
936 mailimap_body_type_basic is a basic field (with Content-Type other
937 than multipart/xxx, message/rfc2822 and text/xxx
938
939 - media_basic will be the MIME type of the part
940
941 - body_fields will be the parsed fields of the MIME part
942*/
943
944struct mailimap_body_type_basic {
945 struct mailimap_media_basic * bd_media_basic; /* != NULL */
946 struct mailimap_body_fields * bd_fields; /* != NULL */
947};
948
949struct mailimap_body_type_basic *
950mailimap_body_type_basic_new(struct mailimap_media_basic * bd_media_basic,
951 struct mailimap_body_fields * bd_fields);
952
953void mailimap_body_type_basic_free(struct mailimap_body_type_basic *
954 body_type_basic);
955
956/*
957 mailimap_body_type_mpart is a MIME multipart.
958
959 - body_list is the list of sub-parts.
960
961 - media_subtype is the subtype of the multipart (for example
962 in multipart/alternative, this is "alternative")
963
964 - body_ext_mpart is the extended fields of the MIME multipart
965*/
966
967struct mailimap_body_type_mpart {
968 clist * bd_list; /* list of (struct mailimap_body *) */
969 /* != NULL */
970 char * bd_media_subtype; /* != NULL */
971 struct mailimap_body_ext_mpart * bd_ext_mpart; /* can be NULL */
972};
973
974struct mailimap_body_type_mpart *
975mailimap_body_type_mpart_new(clist * bd_list, char * bd_media_subtype,
976 struct mailimap_body_ext_mpart * bd_ext_mpart);
977
978void mailimap_body_type_mpart_free(struct mailimap_body_type_mpart *
979 body_type_mpart);
980
981/*
982 mailimap_body_type_msg is a MIME message part
983
984 - body_fields is the MIME fields of the MIME message part
985
986 - envelope is the list of parsed RFC 822 fields of the MIME message
987
988 - body is the sub-part of the message
989
990 - body_lines is the number of lines of the message part
991*/
992
993struct mailimap_body_type_msg {
994 struct mailimap_body_fields * bd_fields; /* != NULL */
995 struct mailimap_envelope * bd_envelope; /* != NULL */
996 struct mailimap_body * bd_body; /* != NULL */
997 uint32_t bd_lines;
998};
999
1000struct mailimap_body_type_msg *
1001mailimap_body_type_msg_new(struct mailimap_body_fields * bd_fields,
1002 struct mailimap_envelope * bd_envelope,
1003 struct mailimap_body * bd_body,
1004 uint32_t bd_lines);
1005
1006void
1007mailimap_body_type_msg_free(struct mailimap_body_type_msg * body_type_msg);
1008
1009
1010
1011/*
1012 mailimap_body_type_text is a single MIME part where Content-Type is text/xxx
1013
1014 - media-text is the subtype of the text part (for example, in "text/plain",
1015 this is "plain", should be allocated with malloc()
1016
1017 - body_fields is the MIME fields of the MIME message part
1018
1019 - body_lines is the number of lines of the message part
1020*/
1021
1022struct mailimap_body_type_text {
1023 char * bd_media_text; /* != NULL */
1024 struct mailimap_body_fields * bd_fields; /* != NULL */
1025 uint32_t bd_lines;
1026};
1027
1028struct mailimap_body_type_text *
1029mailimap_body_type_text_new(char * bd_media_text,
1030 struct mailimap_body_fields * bd_fields,
1031 uint32_t bd_lines);
1032
1033void
1034mailimap_body_type_text_free(struct mailimap_body_type_text * body_type_text);
1035
1036
1037
1038/* this is the type of capability field */
1039
1040enum {
1041 MAILIMAP_CAPABILITY_AUTH_TYPE, /* when the capability is an
1042 authentication type */
1043 MAILIMAP_CAPABILITY_NAME, /* other type of capability */
1044};
1045
1046/*
1047 mailimap_capability is a capability of the IMAP server
1048
1049 - type is the type of capability, this is either a authentication type
1050 (MAILIMAP_CAPABILITY_AUTH_TYPE) or an other type of capability
1051 (MAILIMAP_CAPABILITY_NAME)
1052
1053 - auth_type is a type of authentication "name" in "AUTH=name",
1054 auth_type can be for example "PLAIN", when this is an authentication type,
1055 should be allocated with malloc()
1056
1057 - name is a type of capability when this is not an authentication type,
1058 should be allocated with malloc()
1059*/
1060
1061struct mailimap_capability {
1062 int cap_type;
1063 union {
1064 char * cap_auth_type; /* can be NULL */
1065 char * cap_name; /* can be NULL */
1066 } cap_data;
1067};
1068
1069struct mailimap_capability *
1070mailimap_capability_new(int cap_type, char * cap_auth_type, char * cap_name);
1071
1072void mailimap_capability_free(struct mailimap_capability * c);
1073
1074
1075
1076
1077/*
1078 mailimap_capability_data is a list of capability
1079
1080 - list is the list of capability
1081*/
1082
1083struct mailimap_capability_data {
1084 clist * cap_list; /* list of (struct mailimap_capability *), != NULL */
1085};
1086
1087struct mailimap_capability_data *
1088mailimap_capability_data_new(clist * cap_list);
1089
1090void
1091mailimap_capability_data_free(struct mailimap_capability_data * cap_data);
1092
1093
1094
1095/* this is the type of continue request data */
1096
1097enum {
1098 MAILIMAP_CONTINUE_REQ_ERROR, /* on parse error */
1099 MAILIMAP_CONTINUE_REQ_TEXT, /* when data is a text response */
1100 MAILIMAP_CONTINUE_REQ_BASE64, /* when data is a base64 response */
1101};
1102
1103/*
1104 mailimap_continue_req is a continue request (a response prefixed by "+")
1105
1106 - type is the type of continue request response
1107 MAILIMAP_CONTINUE_REQ_TEXT (when information data is text),
1108 MAILIMAP_CONTINUE_REQ_BASE64 (when information data is base64)
1109
1110 - text is the information of type text in case of text data
1111
1112 - base64 is base64 encoded data in the other case, should be allocated
1113 with malloc()
1114*/
1115
1116struct mailimap_continue_req {
1117 int cr_type;
1118 union {
1119 struct mailimap_resp_text * cr_text; /* can be NULL */
1120 char * cr_base64; /* can be NULL */
1121 } cr_data;
1122};
1123
1124struct mailimap_continue_req *
1125mailimap_continue_req_new(int cr_type, struct mailimap_resp_text * cr_text,
1126 char * cr_base64);
1127
1128void mailimap_continue_req_free(struct mailimap_continue_req * cont_req);
1129
1130
1131/*
1132 mailimap_date_time is a date
1133
1134 - day is the day of month (1 to 31)
1135
1136 - month (1 to 12)
1137
1138 - year (4 digits)
1139
1140 - hour (0 to 23)
1141
1142 - min (0 to 59)
1143
1144 - sec (0 to 59)
1145
1146 - zone (this is the decimal value that we can read, for example:
1147 for "-0200", the value is -200)
1148*/
1149
1150struct mailimap_date_time {
1151 int dt_day;
1152 int dt_month;
1153 int dt_year;
1154 int dt_hour;
1155 int dt_min;
1156 int dt_sec;
1157 int dt_zone;
1158};
1159
1160struct mailimap_date_time *
1161mailimap_date_time_new(int dt_day, int dt_month, int dt_year, int dt_hour,
1162 int dt_min, int dt_sec, int dt_zone);
1163
1164void mailimap_date_time_free(struct mailimap_date_time * date_time);
1165
1166
1167
1168/*
1169 mailimap_envelope is the list of fields that can be parsed by
1170 the IMAP server.
1171
1172 - date is the (non-parsed) content of the "Date" header field,
1173 should be allocated with malloc()
1174
1175 - subject is the subject of the message, should be allocated with
1176 malloc()
1177
1178 - sender is the the parsed content of the "Sender" field
1179
1180 - reply-to is the parsed content of the "Reply-To" field
1181
1182 - to is the parsed content of the "To" field
1183
1184 - cc is the parsed content of the "Cc" field
1185
1186 - bcc is the parsed content of the "Bcc" field
1187
1188 - in_reply_to is the content of the "In-Reply-To" field,
1189 should be allocated with malloc()
1190
1191 - message_id is the content of the "Message-ID" field,
1192 should be allocated with malloc()
1193*/
1194
1195struct mailimap_envelope {
1196 char * env_date; /* can be NULL */
1197 char * env_subject; /* can be NULL */
1198 struct mailimap_env_from * env_from; /* can be NULL */
1199 struct mailimap_env_sender * env_sender; /* can be NULL */
1200 struct mailimap_env_reply_to * env_reply_to; /* can be NULL */
1201 struct mailimap_env_to * env_to; /* can be NULL */
1202 struct mailimap_env_cc * env_cc; /* can be NULL */
1203 struct mailimap_env_bcc * env_bcc; /* can be NULL */
1204 char * env_in_reply_to; /* can be NULL */
1205 char * env_message_id; /* can be NULL */
1206};
1207
1208struct mailimap_envelope *
1209mailimap_envelope_new(char * env_date, char * env_subject,
1210 struct mailimap_env_from * env_from,
1211 struct mailimap_env_sender * env_sender,
1212 struct mailimap_env_reply_to * env_reply_to,
1213 struct mailimap_env_to * env_to,
1214 struct mailimap_env_cc* env_cc,
1215 struct mailimap_env_bcc * env_bcc,
1216 char * env_in_reply_to, char * env_message_id);
1217
1218void mailimap_envelope_free(struct mailimap_envelope * env);
1219
1220
1221
1222/*
1223 mailimap_env_bcc is the parsed "Bcc" field
1224
1225 - list is the list of addresses
1226*/
1227
1228struct mailimap_env_bcc {
1229 clist * bcc_list; /* list of (struct mailimap_address *), != NULL */
1230};
1231
1232struct mailimap_env_bcc * mailimap_env_bcc_new(clist * bcc_list);
1233
1234void mailimap_env_bcc_free(struct mailimap_env_bcc * env_bcc);
1235
1236
1237/*
1238 mailimap_env_cc is the parsed "Cc" field
1239
1240 - list is the list of addresses
1241*/
1242
1243struct mailimap_env_cc {
1244 clist * cc_list; /* list of (struct mailimap_address *), != NULL */
1245};
1246
1247struct mailimap_env_cc * mailimap_env_cc_new(clist * cc_list);
1248
1249void mailimap_env_cc_free(struct mailimap_env_cc * env_cc);
1250
1251
1252
1253/*
1254 mailimap_env_from is the parsed "From" field
1255
1256 - list is the list of addresses
1257*/
1258
1259struct mailimap_env_from {
1260 clist * frm_list; /* list of (struct mailimap_address *) */
1261 /* != NULL */
1262};
1263
1264struct mailimap_env_from * mailimap_env_from_new(clist * frm_list);
1265
1266void mailimap_env_from_free(struct mailimap_env_from * env_from);
1267
1268
1269
1270/*
1271 mailimap_env_reply_to is the parsed "Reply-To" field
1272
1273 - list is the list of addresses
1274*/
1275
1276struct mailimap_env_reply_to {
1277 clist * rt_list; /* list of (struct mailimap_address *), != NULL */
1278};
1279
1280struct mailimap_env_reply_to * mailimap_env_reply_to_new(clist * rt_list);
1281
1282void
1283mailimap_env_reply_to_free(struct mailimap_env_reply_to * env_reply_to);
1284
1285
1286
1287/*
1288 mailimap_env_sender is the parsed "Sender" field
1289
1290 - list is the list of addresses
1291*/
1292
1293struct mailimap_env_sender {
1294 clist * snd_list; /* list of (struct mailimap_address *), != NULL */
1295};
1296
1297struct mailimap_env_sender * mailimap_env_sender_new(clist * snd_list);
1298
1299void mailimap_env_sender_free(struct mailimap_env_sender * env_sender);
1300
1301
1302
1303/*
1304 mailimap_env_to is the parsed "To" field
1305
1306 - list is the list of addresses
1307*/
1308
1309struct mailimap_env_to {
1310 clist * to_list; /* list of (struct mailimap_address *), != NULL */
1311};
1312
1313struct mailimap_env_to * mailimap_env_to_new(clist * to_list);
1314
1315void mailimap_env_to_free(struct mailimap_env_to * env_to);
1316
1317
1318/* this is the type of flag */
1319
1320enum {
1321 MAILIMAP_FLAG_ANSWERED, /* \Answered flag */
1322 MAILIMAP_FLAG_FLAGGED, /* \Flagged flag */
1323 MAILIMAP_FLAG_DELETED, /* \Deleted flag */
1324 MAILIMAP_FLAG_SEEN, /* \Seen flag */
1325 MAILIMAP_FLAG_DRAFT, /* \Draft flag */
1326 MAILIMAP_FLAG_KEYWORD, /* keyword flag */
1327 MAILIMAP_FLAG_EXTENSION, /* \extension flag */
1328};
1329
1330
1331/*
1332 mailimap_flag is a message flag (that we can associate with a message)
1333
1334 - type is the type of the flag, MAILIMAP_FLAG_XXX
1335
1336 - keyword is the flag when the flag is of keyword type,
1337 should be allocated with malloc()
1338
1339 - extension is the flag when the flag is of extension type, should be
1340 allocated with malloc()
1341*/
1342
1343struct mailimap_flag {
1344 int fl_type;
1345 union {
1346 char * fl_keyword; /* can be NULL */
1347 char * fl_extension; /* can be NULL */
1348 } fl_data;
1349};
1350
1351struct mailimap_flag * mailimap_flag_new(int fl_type,
1352 char * fl_keyword, char * fl_extension);
1353
1354void mailimap_flag_free(struct mailimap_flag * f);
1355
1356
1357
1358
1359/* this is the type of flag */
1360
1361enum {
1362 MAILIMAP_FLAG_FETCH_ERROR, /* on parse error */
1363 MAILIMAP_FLAG_FETCH_RECENT, /* \Recent flag */
1364 MAILIMAP_FLAG_FETCH_OTHER, /* other type of flag */
1365};
1366
1367/*
1368 mailimap_flag_fetch is a message flag (when we fetch it)
1369
1370 - type is the type of flag fetch
1371
1372 - flag is the flag when this is not a \Recent flag
1373*/
1374
1375struct mailimap_flag_fetch {
1376 int fl_type;
1377 struct mailimap_flag * fl_flag; /* can be NULL */
1378};
1379
1380struct mailimap_flag_fetch *
1381mailimap_flag_fetch_new(int fl_type, struct mailimap_flag * fl_flag);
1382
1383void mailimap_flag_fetch_free(struct mailimap_flag_fetch * flag_fetch);
1384
1385
1386
1387
1388/* this is the type of flag */
1389
1390enum {
1391 MAILIMAP_FLAG_PERM_ERROR, /* on parse error */
1392 MAILIMAP_FLAG_PERM_FLAG, /* to specify that usual flags can be changed */
1393 MAILIMAP_FLAG_PERM_ALL /* to specify that new flags can be created */
1394};
1395
1396
1397/*
1398 mailimap_flag_perm is a flag returned in case of PERMANENTFLAGS response
1399
1400 - type is the type of returned PERMANENTFLAGS, it can be
1401 MAILIMAP_FLAG_PERM_FLAG (the given flag can be changed permanently) or
1402 MAILIMAP_FLAG_PERM_ALL (new flags can be created)
1403
1404 - flag is the given flag when type is MAILIMAP_FLAG_PERM_FLAG
1405*/
1406
1407struct mailimap_flag_perm {
1408 int fl_type;
1409 struct mailimap_flag * fl_flag; /* can be NULL */
1410};
1411
1412struct mailimap_flag_perm *
1413mailimap_flag_perm_new(int fl_type, struct mailimap_flag * fl_flag);
1414
1415void mailimap_flag_perm_free(struct mailimap_flag_perm * flag_perm);
1416
1417
1418/*
1419 mailimap_flag_list is a list of flags
1420
1421 - list is a list of flags
1422*/
1423
1424struct mailimap_flag_list {
1425 clist * fl_list; /* list of (struct mailimap_flag *), != NULL */
1426};
1427
1428struct mailimap_flag_list *
1429mailimap_flag_list_new(clist * fl_list);
1430
1431void mailimap_flag_list_free(struct mailimap_flag_list * flag_list);
1432
1433
1434
1435
1436/* this is the type of greeting response */
1437
1438enum {
1439 MAILIMAP_GREETING_RESP_COND_ERROR, /* on parse error */
1440 MAILIMAP_GREETING_RESP_COND_AUTH, /* when connection is accepted */
1441 MAILIMAP_GREETING_RESP_COND_BYE, /* when connection is refused */
1442};
1443
1444/*
1445 mailimap_greeting is the response returned on connection
1446
1447 - type is the type of response on connection, either
1448 MAILIMAP_GREETING_RESP_COND_AUTH if connection is accepted or
1449 MAIMIMAP_GREETING_RESP_COND_BYE if connection is refused
1450*/
1451
1452struct mailimap_greeting {
1453 int gr_type;
1454 union {
1455 struct mailimap_resp_cond_auth * gr_auth; /* can be NULL */
1456 struct mailimap_resp_cond_bye * gr_bye; /* can be NULL */
1457 } gr_data;
1458};
1459
1460struct mailimap_greeting *
1461mailimap_greeting_new(int gr_type,
1462 struct mailimap_resp_cond_auth * gr_auth,
1463 struct mailimap_resp_cond_bye * gr_bye);
1464
1465void mailimap_greeting_free(struct mailimap_greeting * greeting);
1466
1467
1468/*
1469 mailimap_header_list is a list of headers that can be specified when
1470 we want to fetch fields
1471
1472 - list is a list of header names, each header name should be allocated
1473 with malloc()
1474*/
1475
1476struct mailimap_header_list {
1477 clist * hdr_list; /* list of astring (char *), != NULL */
1478};
1479
1480struct mailimap_header_list *
1481mailimap_header_list_new(clist * hdr_list);
1482
1483void
1484mailimap_header_list_free(struct mailimap_header_list * header_list);
1485
1486
1487
1488/* this is the type of mailbox STATUS that can be returned */
1489
1490enum {
1491 MAILIMAP_STATUS_ATT_MESSAGES, /* when requesting the number of
1492 messages */
1493 MAILIMAP_STATUS_ATT_RECENT, /* when requesting the number of
1494 recent messages */
1495 MAILIMAP_STATUS_ATT_UIDNEXT, /* when requesting the next unique
1496 identifier */
1497 MAILIMAP_STATUS_ATT_UIDVALIDITY, /* when requesting the validity of
1498 message unique identifiers*/
1499 MAILIMAP_STATUS_ATT_UNSEEN, /* when requesting the number of
1500 unseen messages */
1501};
1502
1503/*
1504 mailimap_status_info is a returned information when a STATUS of
1505 a mailbox is requested
1506
1507 - att is the type of mailbox STATUS, the value can be
1508 MAILIMAP_STATUS_ATT_MESSAGES, MAILIMAP_STATUS_ATT_RECENT,
1509 MAILIMAP_STATUS_ATT_UIDNEXT, MAILIMAP_STATUS_ATT_UIDVALIDITY or
1510 MAILIMAP_STATUS_ATT_UNSEEN
1511
1512 - value is the value of the given information
1513*/
1514
1515struct mailimap_status_info {
1516 int st_att;
1517 uint32_t st_value;
1518};
1519
1520struct mailimap_status_info *
1521mailimap_status_info_new(int st_att, uint32_t st_value);
1522
1523void mailimap_status_info_free(struct mailimap_status_info * info);
1524
1525
1526
1527/*
1528 mailimap_mailbox_data_status is the list of information returned
1529 when a STATUS of a mailbox is requested
1530
1531 - mailbox is the name of the mailbox, should be allocated with malloc()
1532
1533 - status_info_list is the list of information returned
1534*/
1535
1536struct mailimap_mailbox_data_status {
1537 char * st_mailbox;
1538 clist * st_info_list; /* list of (struct mailimap_status_info *) */
1539 /* can be NULL */
1540};
1541
1542struct mailimap_mailbox_data_status *
1543mailimap_mailbox_data_status_new(char * st_mailbox,
1544 clist * st_info_list);
1545
1546void
1547mailimap_mailbox_data_status_free(struct mailimap_mailbox_data_status * info);
1548
1549
1550
1551/* this is the type of mailbox information that is returned */
1552
1553enum {
1554 MAILIMAP_MAILBOX_DATA_ERROR, /* on parse error */
1555 MAILIMAP_MAILBOX_DATA_FLAGS, /* flag that are applicable to the mailbox */
1556 MAILIMAP_MAILBOX_DATA_LIST, /* this is a mailbox in the list of mailboxes
1557 returned on LIST command*/
1558 MAILIMAP_MAILBOX_DATA_LSUB, /* this is a mailbox in the list of
1559 subscribed mailboxes returned on LSUB
1560 command */
1561 MAILIMAP_MAILBOX_DATA_SEARCH, /* this is a list of messages numbers or
1562 unique identifiers returned
1563 on a SEARCH command*/
1564 MAILIMAP_MAILBOX_DATA_STATUS, /* this is the list of information returned
1565 on a STATUS command */
1566 MAILIMAP_MAILBOX_DATA_EXISTS, /* this is the number of messages in the
1567 mailbox */
1568 MAILIMAP_MAILBOX_DATA_RECENT, /* this is the number of recent messages
1569 in the mailbox */
1570};
1571
1572/*
1573 mailimap_mailbox_data is an information related to a mailbox
1574
1575 - type is the type of mailbox_data that is filled, the value of this field
1576 can be MAILIMAP_MAILBOX_DATA_FLAGS, MAILIMAP_MAILBOX_DATA_LIST,
1577 MAILIMAP_MAILBOX_DATA_LSUB, MAILIMAP_MAILBOX_DATA_SEARCH,
1578 MAILIMAP_MAILBOX_DATA_STATUS, MAILIMAP_MAILBOX_DATA_EXISTS
1579 or MAILIMAP_MAILBOX_DATA_RECENT.
1580
1581 - flags is the flags that are applicable to the mailbox when
1582 type is MAILIMAP_MAILBOX_DATA_FLAGS
1583
1584 - list is a mailbox in the list of mailboxes returned on LIST command
1585 when type is MAILIMAP_MAILBOX_DATA_LIST
1586
1587 - lsub is a mailbox in the list of subscribed mailboxes returned on
1588 LSUB command when type is MAILIMAP_MAILBOX_DATA_LSUB
1589
1590 - search is a list of messages numbers or unique identifiers returned
1591 on SEARCH command when type MAILIMAP_MAILBOX_DATA_SEARCH, each element
1592 should be allocated with malloc()
1593
1594 - status is a list of information returned on STATUS command when
1595 type is MAILIMAP_MAILBOX_DATA_STATUS
1596
1597 - exists is the number of messages in the mailbox when type
1598 is MAILIMAP_MAILBOX_DATA_EXISTS
1599
1600 - recent is the number of recent messages in the mailbox when type
1601 is MAILIMAP_MAILBOX_DATA_RECENT
1602*/
1603
1604struct mailimap_mailbox_data {
1605 int mbd_type;
1606 union {
1607 struct mailimap_flag_list * mbd_flags; /* can be NULL */
1608 struct mailimap_mailbox_list * mbd_list; /* can be NULL */
1609 struct mailimap_mailbox_list * mbd_lsub; /* can be NULL */
1610 clist * mbd_search; /* list of nz-number (uint32_t *), can be NULL */
1611 struct mailimap_mailbox_data_status * mbd_status; /* can be NULL */
1612 uint32_t mbd_exists;
1613 uint32_t mbd_recent;
1614 } mbd_data;
1615};
1616
1617struct mailimap_mailbox_data *
1618mailimap_mailbox_data_new(int mbd_type, struct mailimap_flag_list * mbd_flags,
1619 struct mailimap_mailbox_list * mbd_list,
1620 struct mailimap_mailbox_list * mbd_lsub,
1621 clist * mbd_search,
1622 struct mailimap_mailbox_data_status * mbd_status,
1623 uint32_t mbd_exists,
1624 uint32_t mbd_recent);
1625
1626void
1627mailimap_mailbox_data_free(struct mailimap_mailbox_data * mb_data);
1628
1629
1630
1631/* this is the type of mailbox flags */
1632
1633enum {
1634 MAILIMAP_MBX_LIST_FLAGS_SFLAG, /* mailbox single flag - a flag in
1635 {\NoSelect, \Marked, \Unmarked} */
1636 MAILIMAP_MBX_LIST_FLAGS_NO_SFLAG, /* mailbox other flag - mailbox flag
1637 other than \NoSelect \Marked and
1638 \Unmarked) */
1639};
1640
1641/* this is a single flag type */
1642
1643enum {
1644 MAILIMAP_MBX_LIST_SFLAG_ERROR,
1645 MAILIMAP_MBX_LIST_SFLAG_MARKED,
1646 MAILIMAP_MBX_LIST_SFLAG_NOSELECT,
1647 MAILIMAP_MBX_LIST_SFLAG_UNMARKED
1648};
1649
1650/*
1651 mailimap_mbx_list_flags is a mailbox flag
1652
1653 - type is the type of mailbox flag, it can be MAILIMAP_MBX_LIST_FLAGS_SFLAG,
1654 or MAILIMAP_MBX_LIST_FLAGS_NO_SFLAG.
1655
1656 - oflags is a list of "mailbox other flag"
1657
1658 - sflag is a mailbox single flag
1659*/
1660
1661struct mailimap_mbx_list_flags {
1662 int mbf_type;
1663 clist * mbf_oflags; /* list of
1664 (struct mailimap_mbx_list_oflag *), != NULL */
1665 int mbf_sflag;
1666};
1667
1668struct mailimap_mbx_list_flags *
1669mailimap_mbx_list_flags_new(int mbf_type,
1670 clist * mbf_oflags, int mbf_sflag);
1671
1672void
1673mailimap_mbx_list_flags_free(struct mailimap_mbx_list_flags * mbx_list_flags);
1674
1675
1676
1677/* this is the type of the mailbox other flag */
1678
1679enum {
1680 MAILIMAP_MBX_LIST_OFLAG_ERROR, /* on parse error */
1681 MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS, /* \NoInferior flag */
1682 MAILIMAP_MBX_LIST_OFLAG_FLAG_EXT /* other flag */
1683};
1684
1685/*
1686 mailimap_mbx_list_oflag is a mailbox other flag
1687
1688 - type can be MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS when this is
1689 a \NoInferior flag or MAILIMAP_MBX_LIST_OFLAG_FLAG_EXT
1690
1691 - flag_ext is set when MAILIMAP_MBX_LIST_OFLAG_FLAG_EXT and is
1692 an extension flag, should be allocated with malloc()
1693*/
1694
1695struct mailimap_mbx_list_oflag {
1696 int of_type;
1697 char * of_flag_ext; /* can be NULL */
1698};
1699
1700struct mailimap_mbx_list_oflag *
1701mailimap_mbx_list_oflag_new(int of_type, char * of_flag_ext);
1702
1703void
1704mailimap_mbx_list_oflag_free(struct mailimap_mbx_list_oflag * oflag);
1705
1706
1707
1708/*
1709 mailimap_mailbox_list is a list of mailbox flags
1710
1711 - mb_flag is a list of mailbox flags
1712
1713 - delimiter is the delimiter of the mailbox path
1714
1715 - mb is the name of the mailbox, should be allocated with malloc()
1716*/
1717
1718struct mailimap_mailbox_list {
1719 struct mailimap_mbx_list_flags * mb_flag; /* can be NULL */
1720 char mb_delimiter;
1721 char * mb_name; /* != NULL */
1722};
1723
1724struct mailimap_mailbox_list *
1725mailimap_mailbox_list_new(struct mailimap_mbx_list_flags * mbx_flags,
1726 char mb_delimiter, char * mb_name);
1727
1728void
1729mailimap_mailbox_list_free(struct mailimap_mailbox_list * mb_list);
1730
1731
1732
1733/* this is the MIME type */
1734
1735enum {
1736 MAILIMAP_MEDIA_BASIC_APPLICATION, /* application/xxx */
1737 MAILIMAP_MEDIA_BASIC_AUDIO, /* audio/xxx */
1738 MAILIMAP_MEDIA_BASIC_IMAGE, /* image/xxx */
1739 MAILIMAP_MEDIA_BASIC_MESSAGE, /* message/xxx */
1740 MAILIMAP_MEDIA_BASIC_VIDEO, /* video/xxx */
1741 MAILIMAP_MEDIA_BASIC_OTHER, /* for all other cases */
1742};
1743
1744
1745/*
1746 mailimap_media_basic is the MIME type
1747
1748 - type can be MAILIMAP_MEDIA_BASIC_APPLICATION, MAILIMAP_MEDIA_BASIC_AUDIO,
1749 MAILIMAP_MEDIA_BASIC_IMAGE, MAILIMAP_MEDIA_BASIC_MESSAGE,
1750 MAILIMAP_MEDIA_BASIC_VIDEO or MAILIMAP_MEDIA_BASIC_OTHER
1751
1752 - basic_type is defined when type is MAILIMAP_MEDIA_BASIC_OTHER, should
1753 be allocated with malloc()
1754
1755 - subtype is the subtype of the MIME type, for example, this is
1756 "data" in "application/data", should be allocated with malloc()
1757*/
1758
1759struct mailimap_media_basic {
1760 int med_type;
1761 char * med_basic_type; /* can be NULL */
1762 char * med_subtype; /* != NULL */
1763};
1764
1765struct mailimap_media_basic *
1766mailimap_media_basic_new(int med_type,
1767 char * med_basic_type, char * med_subtype);
1768
1769void
1770mailimap_media_basic_free(struct mailimap_media_basic * media_basic);
1771
1772
1773
1774/* this is the type of message data */
1775
1776enum {
1777 MAILIMAP_MESSAGE_DATA_ERROR,
1778 MAILIMAP_MESSAGE_DATA_EXPUNGE,
1779 MAILIMAP_MESSAGE_DATA_FETCH
1780};
1781
1782/*
1783 mailimap_message_data is an information related to a message
1784
1785 - number is the number or the unique identifier of the message
1786
1787 - type is the type of information, this value can be
1788 MAILIMAP_MESSAGE_DATA_EXPUNGE or MAILIMAP_MESSAGE_DATA_FETCH
1789
1790 - msg_att is the message data
1791*/
1792
1793struct mailimap_message_data {
1794 uint32_t mdt_number;
1795 int mdt_type;
1796 struct mailimap_msg_att * mdt_msg_att; /* can be NULL */
1797 /* if type = EXPUNGE, can be NULL */
1798};
1799
1800struct mailimap_message_data *
1801mailimap_message_data_new(uint32_t mdt_number, int mdt_type,
1802 struct mailimap_msg_att * mdt_msg_att);
1803
1804void
1805mailimap_message_data_free(struct mailimap_message_data * msg_data);
1806
1807
1808
1809/* this the type of the message attributes */
1810
1811enum {
1812 MAILIMAP_MSG_ATT_ITEM_ERROR, /* on parse error */
1813 MAILIMAP_MSG_ATT_ITEM_DYNAMIC, /* dynamic message attributes (flags) */
1814 MAILIMAP_MSG_ATT_ITEM_STATIC, /* static messages attributes
1815 (message content) */
1816};
1817
1818/*
1819 mailimap_msg_att_item is a message attribute
1820
1821 - type is the type of message attribute, the value can be
1822 MAILIMAP_MSG_ATT_ITEM_DYNAMIC or MAILIMAP_MSG_ATT_ITEM_STATIC
1823
1824 - msg_att_dyn is a dynamic message attribute when type is
1825 MAILIMAP_MSG_ATT_ITEM_DYNAMIC
1826
1827 - msg_att_static is a static message attribute when type is
1828 MAILIMAP_MSG_ATT_ITEM_STATIC
1829*/
1830
1831struct mailimap_msg_att_item {
1832 int att_type;
1833 union {
1834 struct mailimap_msg_att_dynamic * att_dyn; /* can be NULL */
1835 struct mailimap_msg_att_static * att_static; /* can be NULL */
1836 } att_data;
1837};
1838
1839struct mailimap_msg_att_item *
1840mailimap_msg_att_item_new(int att_type,
1841 struct mailimap_msg_att_dynamic * att_dyn,
1842 struct mailimap_msg_att_static * att_static);
1843
1844void
1845mailimap_msg_att_item_free(struct mailimap_msg_att_item * item);
1846
1847
1848/*
1849 mailimap_msg_att is a list of attributes
1850
1851 - list is a list of message attributes
1852
1853 - number is the message number or unique identifier, this field
1854 has been added for implementation purpose
1855*/
1856
1857struct mailimap_msg_att {
1858 clist * att_list; /* list of (struct mailimap_msg_att_item *) */
1859 /* != NULL */
1860 uint32_t att_number; /* extra field to store the message number,
1861 used for mailimap */
1862};
1863
1864struct mailimap_msg_att * mailimap_msg_att_new(clist * att_list);
1865
1866void mailimap_msg_att_free(struct mailimap_msg_att * msg_att);
1867
1868
1869/*
1870 mailimap_msg_att_dynamic is a dynamic message attribute
1871
1872 - list is a list of flags (that have been fetched)
1873*/
1874
1875struct mailimap_msg_att_dynamic {
1876 clist * att_list; /* list of (struct mailimap_flag_fetch *) */
1877 /* can be NULL */
1878};
1879
1880struct mailimap_msg_att_dynamic *
1881mailimap_msg_att_dynamic_new(clist * att_list);
1882
1883void
1884mailimap_msg_att_dynamic_free(struct mailimap_msg_att_dynamic * msg_att_dyn);
1885
1886
1887
1888/*
1889 mailimap_msg_att_body_section is a MIME part content
1890
1891 - section is the location of the MIME part in the message
1892
1893 - origin_octet is the offset of the requested part of the MIME part
1894
1895 - body_part is the content or partial content of the MIME part,
1896 should be allocated through a MMAPString
1897
1898 - length is the size of the content
1899*/
1900
1901struct mailimap_msg_att_body_section {
1902 struct mailimap_section * sec_section; /* != NULL */
1903 uint32_t sec_origin_octet;
1904 char * sec_body_part; /* can be NULL */
1905 size_t sec_length;
1906};
1907
1908struct mailimap_msg_att_body_section *
1909mailimap_msg_att_body_section_new(struct mailimap_section * section,
1910 uint32_t sec_origin_octet,
1911 char * sec_body_part,
1912 size_t sec_length);
1913
1914void
1915mailimap_msg_att_body_section_free(struct mailimap_msg_att_body_section *
1916 msg_att_body_section);
1917
1918
1919
1920/*
1921 this is the type of static message attribute
1922*/
1923
1924enum {
1925 MAILIMAP_MSG_ATT_ERROR, /* on parse error */
1926 MAILIMAP_MSG_ATT_ENVELOPE, /* this is the fields that can be
1927 parsed by the server */
1928 MAILIMAP_MSG_ATT_INTERNALDATE, /* this is the message date kept
1929 by the server */
1930 MAILIMAP_MSG_ATT_RFC822, /* this is the message content
1931 (header and body) */
1932 MAILIMAP_MSG_ATT_RFC822_HEADER, /* this is the message header */
1933 MAILIMAP_MSG_ATT_RFC822_TEXT, /* this is the message text part */
1934 MAILIMAP_MSG_ATT_RFC822_SIZE, /* this is the size of the message content */
1935 MAILIMAP_MSG_ATT_BODY, /* this is the MIME description of
1936 the message */
1937 MAILIMAP_MSG_ATT_BODYSTRUCTURE, /* this is the MIME description of the
1938 message with additional information */
1939 MAILIMAP_MSG_ATT_BODY_SECTION, /* this is a MIME part content */
1940 MAILIMAP_MSG_ATT_UID, /* this is the message unique identifier */
1941};
1942
1943/*
1944 mailimap_msg_att_static is a given part of the message
1945
1946 - type is the type of the static message attribute, the value can be
1947 MAILIMAP_MSG_ATT_ENVELOPE, MAILIMAP_MSG_ATT_INTERNALDATE,
1948 MAILIMAP_MSG_ATT_RFC822, MAILIMAP_MSG_ATT_RFC822_HEADER,
1949 MAILIMAP_MSG_ATT_RFC822_TEXT, MAILIMAP_MSG_ATT_RFC822_SIZE,
1950 MAILIMAP_MSG_ATT_BODY, MAILIMAP_MSG_ATT_BODYSTRUCTURE,
1951 MAILIMAP_MSG_ATT_BODY_SECTION, MAILIMAP_MSG_ATT_UID
1952
1953 - env is the headers parsed by the server if type is
1954 MAILIMAP_MSG_ATT_ENVELOPE
1955
1956 - internal_date is the date of message kept by the server if type is
1957 MAILIMAP_MSG_ATT_INTERNALDATE
1958
1959 - rfc822 is the message content if type is MAILIMAP_MSG_ATT_RFC822,
1960 should be allocated through a MMAPString
1961
1962 - rfc822_header is the message header if type is
1963 MAILIMAP_MSG_ATT_RFC822_HEADER, should be allocated through a MMAPString
1964
1965 - rfc822_text is the message text part if type is
1966 MAILIMAP_MSG_ATT_RFC822_TEXT, should be allocated through a MMAPString
1967
1968 - rfc822_size is the message size if type is MAILIMAP_MSG_ATT_SIZE
1969
1970 - body is the MIME description of the message
1971
1972 - bodystructure is the MIME description of the message with additional
1973 information
1974
1975 - body_section is a MIME part content
1976
1977 - uid is a unique message identifier
1978*/
1979
1980struct mailimap_msg_att_static {
1981 int att_type;
1982 union {
1983 struct mailimap_envelope * att_env; /* can be NULL */
1984 struct mailimap_date_time * att_internal_date; /* can be NULL */
1985 struct {
1986 char * att_content; /* can be NULL */
1987 size_t att_length;
1988 } att_rfc822;
1989 struct {
1990 char * att_content; /* can be NULL */
1991 size_t att_length;
1992 } att_rfc822_header;
1993 struct {
1994 char * att_content; /* can be NULL */
1995 size_t att_length;
1996 } att_rfc822_text;
1997 uint32_t att_rfc822_size;
1998 struct mailimap_body * att_bodystructure; /* can be NULL */
1999 struct mailimap_body * att_body; /* can be NULL */
2000 struct mailimap_msg_att_body_section * att_body_section; /* can be NULL */
2001 uint32_t att_uid;
2002 } att_data;
2003};
2004
2005struct mailimap_msg_att_static *
2006mailimap_msg_att_static_new(int att_type, struct mailimap_envelope * att_env,
2007 struct mailimap_date_time * att_internal_date,
2008 char * att_rfc822,
2009 char * att_rfc822_header,
2010 char * att_rfc822_text,
2011 size_t att_length,
2012 uint32_t att_rfc822_size,
2013 struct mailimap_body * att_bodystructure,
2014 struct mailimap_body * att_body,
2015 struct mailimap_msg_att_body_section * att_body_section,
2016 uint32_t att_uid);
2017
2018void
2019mailimap_msg_att_static_free(struct mailimap_msg_att_static * item);
2020
2021
2022
2023/* this is the type of a response element */
2024
2025enum {
2026 MAILIMAP_RESP_ERROR, /* on parse error */
2027 MAILIMAP_RESP_CONT_REQ, /* continuation request */
2028 MAILIMAP_RESP_RESP_DATA, /* response data */
2029};
2030
2031/*
2032 mailimap_cont_req_or_resp_data is a response element
2033
2034 - type is the type of response, the value can be MAILIMAP_RESP_CONT_REQ
2035 or MAILIMAP_RESP_RESP_DATA
2036
2037 - cont_req is a continuation request
2038
2039 - resp_data is a reponse data
2040*/
2041
2042struct mailimap_cont_req_or_resp_data {
2043 int rsp_type;
2044 union {
2045 struct mailimap_continue_req * rsp_cont_req; /* can be NULL */
2046 struct mailimap_response_data * rsp_resp_data; /* can be NULL */
2047 } rsp_data;
2048};
2049
2050struct mailimap_cont_req_or_resp_data *
2051mailimap_cont_req_or_resp_data_new(int rsp_type,
2052 struct mailimap_continue_req * rsp_cont_req,
2053 struct mailimap_response_data * rsp_resp_data);
2054
2055void
2056mailimap_cont_req_or_resp_data_free(struct mailimap_cont_req_or_resp_data *
2057 cont_req_or_resp_data);
2058
2059
2060/*
2061 mailimap_response is a list of response elements
2062
2063 - cont_req_or_resp_data_list is a list of response elements
2064
2065 - resp_done is an ending response element
2066*/
2067
2068struct mailimap_response {
2069 clist * rsp_cont_req_or_resp_data_list;
2070 /* list of (struct mailiap_cont_req_or_resp_data *) */
2071 /* can be NULL */
2072 struct mailimap_response_done * rsp_resp_done; /* != NULL */
2073};
2074
2075struct mailimap_response *
2076mailimap_response_new(clist * rsp_cont_req_or_resp_data_list,
2077 struct mailimap_response_done * rsp_resp_done);
2078
2079void
2080mailimap_response_free(struct mailimap_response * resp);
2081
2082
2083
2084/* this is the type of an untagged response */
2085
2086enum {
2087 MAILIMAP_RESP_DATA_TYPE_ERROR, /* on parse error */
2088 MAILIMAP_RESP_DATA_TYPE_COND_STATE, /* condition state response */
2089 MAILIMAP_RESP_DATA_TYPE_COND_BYE, /* BYE response (server is about
2090 to close the connection) */
2091 MAILIMAP_RESP_DATA_TYPE_MAILBOX_DATA, /* response related to a mailbox */
2092 MAILIMAP_RESP_DATA_TYPE_MESSAGE_DATA, /* response related to a message */
2093 MAILIMAP_RESP_DATA_TYPE_CAPABILITY_DATA, /* capability information */
2094};
2095
2096/*
2097 mailimap_reponse_data is an untagged response
2098
2099 - type is the type of the untagged response, it can be
2100 MAILIMAP_RESP_DATA_COND_STATE, MAILIMAP_RESP_DATA_COND_BYE,
2101 MAILIMAP_RESP_DATA_MAILBOX_DATA, MAILIMAP_RESP_DATA_MESSAGE_DATA
2102 or MAILIMAP_RESP_DATA_CAPABILITY_DATA
2103
2104 - cond_state is a condition state response
2105
2106 - bye is a BYE response (server is about to close the connection)
2107
2108 - mailbox_data is a response related to a mailbox
2109
2110 - message_data is a response related to a message
2111
2112 - capability is information about capabilities
2113*/
2114
2115struct mailimap_response_data {
2116 int rsp_type;
2117 union {
2118 struct mailimap_resp_cond_state * rsp_cond_state; /* can be NULL */
2119 struct mailimap_resp_cond_bye * rsp_bye; /* can be NULL */
2120 struct mailimap_mailbox_data * rsp_mailbox_data; /* can be NULL */
2121 struct mailimap_message_data * rsp_message_data; /* can be NULL */
2122 struct mailimap_capability_data * rsp_capability_data; /* can be NULL */
2123 } rsp_data;
2124};
2125
2126struct mailimap_response_data *
2127mailimap_response_data_new(int rsp_type,
2128 struct mailimap_resp_cond_state * rsp_cond_state,
2129 struct mailimap_resp_cond_bye * rsp_bye,
2130 struct mailimap_mailbox_data * rsp_mailbox_data,
2131 struct mailimap_message_data * rsp_message_data,
2132 struct mailimap_capability_data * rsp_capability_data);
2133
2134void
2135mailimap_response_data_free(struct mailimap_response_data * resp_data);
2136
2137
2138
2139/* this is the type of an ending response */
2140
2141enum {
2142 MAILIMAP_RESP_DONE_TYPE_ERROR, /* on parse error */
2143 MAILIMAP_RESP_DONE_TYPE_TAGGED, /* tagged response */
2144 MAILIMAP_RESP_DONE_TYPE_FATAL, /* fatal error response */
2145};
2146
2147/*
2148 mailimap_response_done is an ending response
2149
2150 - type is the type of the ending response
2151
2152 - tagged is a tagged response
2153
2154 - fatal is a fatal error response
2155*/
2156
2157struct mailimap_response_done {
2158 int rsp_type;
2159 union {
2160 struct mailimap_response_tagged * rsp_tagged; /* can be NULL */
2161 struct mailimap_response_fatal * rsp_fatal; /* can be NULL */
2162 } rsp_data;
2163};
2164
2165struct mailimap_response_done *
2166mailimap_response_done_new(int rsp_type,
2167 struct mailimap_response_tagged * rsp_tagged,
2168 struct mailimap_response_fatal * rsp_fatal);
2169
2170void mailimap_response_done_free(struct mailimap_response_done *
2171 resp_done);
2172
2173
2174/*
2175 mailimap_response_fatal is a fatal error response
2176
2177 - bye is a BYE response text
2178*/
2179
2180struct mailimap_response_fatal {
2181 struct mailimap_resp_cond_bye * rsp_bye; /* != NULL */
2182};
2183
2184struct mailimap_response_fatal *
2185mailimap_response_fatal_new(struct mailimap_resp_cond_bye * rsp_bye);
2186
2187void mailimap_response_fatal_free(struct mailimap_response_fatal * resp_fatal);
2188
2189
2190
2191/*
2192 mailimap_response_tagged is a tagged response
2193
2194 - tag is the sent tag, should be allocated with malloc()
2195
2196 - cond_state is a condition state response
2197*/
2198
2199struct mailimap_response_tagged {
2200 char * rsp_tag; /* != NULL */
2201 struct mailimap_resp_cond_state * rsp_cond_state; /* != NULL */
2202};
2203
2204struct mailimap_response_tagged *
2205mailimap_response_tagged_new(char * rsp_tag,
2206 struct mailimap_resp_cond_state * rsp_cond_state);
2207
2208void
2209mailimap_response_tagged_free(struct mailimap_response_tagged * tagged);
2210
2211
2212/* this is the type of an authentication condition response */
2213
2214enum {
2215 MAILIMAP_RESP_COND_AUTH_ERROR, /* on parse error */
2216 MAILIMAP_RESP_COND_AUTH_OK, /* authentication is needed */
2217 MAILIMAP_RESP_COND_AUTH_PREAUTH, /* authentication is not needed */
2218};
2219
2220/*
2221 mailimap_resp_cond_auth is an authentication condition response
2222
2223 - type is the type of the authentication condition response,
2224 the value can be MAILIMAP_RESP_COND_AUTH_OK or
2225 MAILIMAP_RESP_COND_AUTH_PREAUTH
2226
2227 - text is a text response
2228*/
2229
2230struct mailimap_resp_cond_auth {
2231 int rsp_type;
2232 struct mailimap_resp_text * rsp_text; /* != NULL */
2233};
2234
2235struct mailimap_resp_cond_auth *
2236mailimap_resp_cond_auth_new(int rsp_type,
2237 struct mailimap_resp_text * rsp_text);
2238
2239void
2240mailimap_resp_cond_auth_free(struct mailimap_resp_cond_auth * cond_auth);
2241
2242
2243
2244/*
2245 mailimap_resp_cond_bye is a BYE response
2246
2247 - text is a text response
2248*/
2249
2250struct mailimap_resp_cond_bye {
2251 struct mailimap_resp_text * rsp_text; /* != NULL */
2252};
2253
2254struct mailimap_resp_cond_bye *
2255mailimap_resp_cond_bye_new(struct mailimap_resp_text * rsp_text);
2256
2257void
2258mailimap_resp_cond_bye_free(struct mailimap_resp_cond_bye * cond_bye);
2259
2260
2261
2262/* this is the type of a condition state response */
2263
2264enum {
2265 MAILIMAP_RESP_COND_STATE_OK,
2266 MAILIMAP_RESP_COND_STATE_NO,
2267 MAILIMAP_RESP_COND_STATE_BAD
2268};
2269
2270/*
2271 mailimap_resp_cond_state is a condition state reponse
2272
2273 - type is the type of the condition state response
2274
2275 - text is a text response
2276*/
2277
2278struct mailimap_resp_cond_state {
2279 int rsp_type;
2280 struct mailimap_resp_text * rsp_text; /* can be NULL */
2281};
2282
2283struct mailimap_resp_cond_state *
2284mailimap_resp_cond_state_new(int rsp_type,
2285 struct mailimap_resp_text * rsp_text);
2286
2287void
2288mailimap_resp_cond_state_free(struct mailimap_resp_cond_state * cond_state);
2289
2290
2291
2292/*
2293 mailimap_resp_text is a text response
2294
2295 - resp_code is a response code
2296
2297 - text is a human readable text, should be allocated with malloc()
2298*/
2299
2300struct mailimap_resp_text {
2301 struct mailimap_resp_text_code * rsp_code; /* can be NULL */
2302 char * rsp_text; /* can be NULL */
2303};
2304
2305struct mailimap_resp_text *
2306mailimap_resp_text_new(struct mailimap_resp_text_code * resp_code,
2307 char * rsp_text);
2308
2309void mailimap_resp_text_free(struct mailimap_resp_text * resp_text);
2310
2311
2312
2313/* this is the type of the response code */
2314
2315enum {
2316 MAILIMAP_RESP_TEXT_CODE_ALERT, /* ALERT response */
2317 MAILIMAP_RESP_TEXT_CODE_BADCHARSET, /* BADCHARSET response */
2318 MAILIMAP_RESP_TEXT_CODE_CAPABILITY_DATA, /* CAPABILITY response */
2319 MAILIMAP_RESP_TEXT_CODE_PARSE, /* PARSE response */
2320 MAILIMAP_RESP_TEXT_CODE_PERMANENTFLAGS, /* PERMANENTFLAGS response */
2321 MAILIMAP_RESP_TEXT_CODE_READ_ONLY, /* READONLY response */
2322 MAILIMAP_RESP_TEXT_CODE_READ_WRITE, /* READWRITE response */
2323 MAILIMAP_RESP_TEXT_CODE_TRY_CREATE, /* TRYCREATE response */
2324 MAILIMAP_RESP_TEXT_CODE_UIDNEXT, /* UIDNEXT response */
2325 MAILIMAP_RESP_TEXT_CODE_UIDVALIDITY, /* UIDVALIDITY response */
2326 MAILIMAP_RESP_TEXT_CODE_UNSEEN, /* UNSEEN response */
2327 MAILIMAP_RESP_TEXT_CODE_OTHER, /* other type of response */
2328};
2329
2330/*
2331 mailimap_resp_text_code is a response code
2332
2333 - type is the type of the response code, the value can be
2334 MAILIMAP_RESP_TEXT_CODE_ALERT, MAILIMAP_RESP_TEXT_CODE_BADCHARSET,
2335 MAILIMAP_RESP_TEXT_CODE_CAPABILITY_DATA, MAILIMAP_RESP_TEXT_CODE_PARSE,
2336 MAILIMAP_RESP_TEXT_CODE_PERMANENTFLAGS, MAILIMAP_RESP_TEXT_CODE_READ_ONLY,
2337 MAILIMAP_RESP_TEXT_CODE_READ_WRITE, MAILIMAP_RESP_TEXT_CODE_TRY_CREATE,
2338 MAILIMAP_RESP_TEXT_CODE_UIDNEXT, MAILIMAP_RESP_TEXT_CODE_UIDVALIDITY,
2339 MAILIMAP_RESP_TEXT_CODE_UNSEEN or MAILIMAP_RESP_TEXT_CODE_OTHER
2340
2341 - badcharset is a list of charsets if type
2342 is MAILIMAP_RESP_TEXT_CODE_BADCHARSET, each element should be
2343 allocated with malloc()
2344
2345 - cap_data is a list of capabilities
2346
2347 - perm_flags is a list of flags, this is the flags that can be changed
2348 permanently on the messages of the mailbox.
2349
2350 - uidnext is the next unique identifier of a message
2351
2352 - uidvalidity is the unique identifier validity value
2353
2354 - first_unseen is the number of the first message without the \Seen flag
2355
2356 - atom is a keyword for an extension response code, should be allocated
2357 with malloc()
2358
2359 - atom_value is the data related with the extension response code,
2360 should be allocated with malloc()
2361*/
2362
2363struct mailimap_resp_text_code {
2364 int rc_type;
2365 union {
2366 clist * rc_badcharset; /* list of astring (char *) */
2367 /* can be NULL */
2368 struct mailimap_capability_data * rc_cap_data; /* != NULL */
2369 clist * rc_perm_flags; /* list of (struct mailimap_flag_perm *) */
2370 /* can be NULL */
2371 uint32_t rc_uidnext;
2372 uint32_t rc_uidvalidity;
2373 uint32_t rc_first_unseen;
2374 struct {
2375 char * atom_name; /* can be NULL */
2376 char * atom_value; /* can be NULL */
2377 } rc_atom;
2378 } rc_data;
2379};
2380
2381struct mailimap_resp_text_code *
2382mailimap_resp_text_code_new(int rc_type, clist * rc_badcharset,
2383 struct mailimap_capability_data * rc_cap_data,
2384 clist * rc_perm_flags,
2385 uint32_t rc_uidnext, uint32_t rc_uidvalidity,
2386 uint32_t rc_first_unseen, char * rc_atom, char * rc_atom_value);
2387
2388void
2389mailimap_resp_text_code_free(struct mailimap_resp_text_code * resp_text_code);
2390
2391
2392/*
2393 mailimap_section is a MIME part section identifier
2394
2395 section_spec is the MIME section identifier
2396*/
2397
2398struct mailimap_section {
2399 struct mailimap_section_spec * sec_spec; /* can be NULL */
2400};
2401
2402struct mailimap_section *
2403mailimap_section_new(struct mailimap_section_spec * sec_spec);
2404
2405void mailimap_section_free(struct mailimap_section * section);
2406
2407
2408/* this is the type of the message/rfc822 part description */
2409
2410enum {
2411 MAILIMAP_SECTION_MSGTEXT_HEADER, /* header fields part of the
2412 message */
2413 MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS, /* given header fields of the
2414 message */
2415 MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT, /* header fields of the
2416 message except the given */
2417 MAILIMAP_SECTION_MSGTEXT_TEXT, /* text part */
2418};
2419
2420/*
2421 mailimap_section_msgtext is a message/rfc822 part description
2422
2423 - type is the type of the content part and the value can be
2424 MAILIMAP_SECTION_MSGTEXT_HEADER, MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS,
2425 MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT
2426 or MAILIMAP_SECTION_MSGTEXT_TEXT
2427
2428 - header_list is the list of headers when type is
2429 MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS or
2430 MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT
2431*/
2432
2433struct mailimap_section_msgtext {
2434 int sec_type;
2435 struct mailimap_header_list * sec_header_list; /* can be NULL */
2436};
2437
2438struct mailimap_section_msgtext *
2439mailimap_section_msgtext_new(int sec_type,
2440 struct mailimap_header_list * sec_header_list);
2441
2442void
2443mailimap_section_msgtext_free(struct mailimap_section_msgtext * msgtext);
2444
2445
2446
2447/*
2448 mailimap_section_part is the MIME part location in a message
2449
2450 - section_id is a list of number index of the sub-part in the mail structure,
2451 each element should be allocated with malloc()
2452
2453*/
2454
2455struct mailimap_section_part {
2456 clist * sec_id; /* list of nz-number (uint32_t *) */
2457 /* != NULL */
2458};
2459
2460struct mailimap_section_part *
2461mailimap_section_part_new(clist * sec_id);
2462
2463void
2464mailimap_section_part_free(struct mailimap_section_part * section_part);
2465
2466
2467
2468/* this is the type of section specification */
2469
2470enum {
2471 MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT, /* if requesting data of the root
2472 MIME message/rfc822 part */
2473 MAILIMAP_SECTION_SPEC_SECTION_PART, /* location of the MIME part
2474 in the message */
2475};
2476
2477/*
2478 mailimap_section_spec is a section specification
2479
2480 - type is the type of the section specification, the value can be
2481 MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT or
2482 MAILIMAP_SECTION_SPEC_SECTION_PART
2483
2484 - section_msgtext is a message/rfc822 part description if type is
2485 MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT
2486
2487 - section_part is a body part location in the message if type is
2488 MAILIMAP_SECTION_SPEC_SECTION_PART
2489
2490 - section_text is a body part location for a given MIME part,
2491 this can be NULL if the body of the part is requested (and not
2492 the MIME header).
2493*/
2494
2495struct mailimap_section_spec {
2496 int sec_type;
2497 union {
2498 struct mailimap_section_msgtext * sec_msgtext; /* can be NULL */
2499 struct mailimap_section_part * sec_part; /* can be NULL */
2500 } sec_data;
2501 struct mailimap_section_text * sec_text; /* can be NULL */
2502};
2503
2504struct mailimap_section_spec *
2505mailimap_section_spec_new(int sec_type,
2506 struct mailimap_section_msgtext * sec_msgtext,
2507 struct mailimap_section_part * sec_part,
2508 struct mailimap_section_text * sec_text);
2509
2510void
2511mailimap_section_spec_free(struct mailimap_section_spec * section_spec);
2512
2513
2514
2515/* this is the type of body part location for a given MIME part */
2516
2517enum {
2518 MAILIMAP_SECTION_TEXT_ERROR, /* on parse error **/
2519 MAILIMAP_SECTION_TEXT_SECTION_MSGTEXT, /* if the MIME type is
2520 message/rfc822, headers or text
2521 can be requested */
2522 MAILIMAP_SECTION_TEXT_MIME, /* for all MIME types,
2523 MIME headers can be requested */
2524};
2525
2526/*
2527 mailimap_section_text is the body part location for a given MIME part
2528
2529 - type can be MAILIMAP_SECTION_TEXT_SECTION_MSGTEXT or
2530 MAILIMAP_SECTION_TEXT_MIME
2531
2532 - section_msgtext is the part of the MIME part when MIME type is
2533 message/rfc822 than can be requested, when type is
2534 MAILIMAP_TEXT_SECTION_MSGTEXT
2535*/
2536
2537struct mailimap_section_text {
2538 int sec_type;
2539 struct mailimap_section_msgtext * sec_msgtext; /* can be NULL */
2540};
2541
2542struct mailimap_section_text *
2543mailimap_section_text_new(int sec_type,
2544 struct mailimap_section_msgtext * sec_msgtext);
2545
2546void
2547mailimap_section_text_free(struct mailimap_section_text * section_text);
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558/* ************************************************************************* */
2559/* the following part concerns only the IMAP command that are sent */
2560
2561
2562/*
2563 mailimap_set_item is a message set
2564
2565 - first is the first message of the set
2566 - last is the last message of the set
2567
2568 this can be message numbers of message unique identifiers
2569*/
2570
2571struct mailimap_set_item {
2572 uint32_t set_first;
2573 uint32_t set_last;
2574};
2575
2576struct mailimap_set_item *
2577mailimap_set_item_new(uint32_t set_first, uint32_t set_last);
2578
2579void mailimap_set_item_free(struct mailimap_set_item * set_item);
2580
2581
2582
2583/*
2584 set is a list of message sets
2585
2586 - list is a list of message sets
2587*/
2588
2589struct mailimap_set {
2590 clist * set_list; /* list of (struct mailimap_set_item *) */
2591};
2592
2593struct mailimap_set * mailimap_set_new(clist * list);
2594
2595void mailimap_set_free(struct mailimap_set * set);
2596
2597
2598/*
2599 mailimap_date is a date
2600
2601 - day is the day in the month (1 to 31)
2602
2603 - month (1 to 12)
2604
2605 - year (4 digits)
2606*/
2607
2608struct mailimap_date {
2609 int dt_day;
2610 int dt_month;
2611 int dt_year;
2612};
2613
2614struct mailimap_date *
2615mailimap_date_new(int dt_day, int dt_month, int dt_year);
2616
2617void mailimap_date_free(struct mailimap_date * date);
2618
2619
2620
2621
2622/* this is the type of fetch attribute for a given message */
2623
2624enum {
2625 MAILIMAP_FETCH_ATT_ENVELOPE, /* to fetch the headers parsed by
2626 the IMAP server */
2627 MAILIMAP_FETCH_ATT_FLAGS, /* to fetch the flags */
2628 MAILIMAP_FETCH_ATT_INTERNALDATE, /* to fetch the date of the message
2629 kept by the server */
2630 MAILIMAP_FETCH_ATT_RFC822, /* to fetch the entire message */
2631 MAILIMAP_FETCH_ATT_RFC822_HEADER, /* to fetch the headers */
2632 MAILIMAP_FETCH_ATT_RFC822_SIZE, /* to fetch the size */
2633 MAILIMAP_FETCH_ATT_RFC822_TEXT, /* to fetch the text part */
2634 MAILIMAP_FETCH_ATT_BODY, /* to fetch the MIME structure */
2635 MAILIMAP_FETCH_ATT_BODYSTRUCTURE, /* to fetch the MIME structure with
2636 additional information */
2637 MAILIMAP_FETCH_ATT_UID, /* to fetch the unique identifier */
2638 MAILIMAP_FETCH_ATT_BODY_SECTION, /* to fetch a given part */
2639 MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION, /* to fetch a given part without
2640 marking the message as read */
2641};
2642
2643
2644/*
2645 mailimap_fetch_att is the description of the fetch attribute
2646
2647 - type is the type of fetch attribute, the value can be
2648 MAILIMAP_FETCH_ATT_ENVELOPE, MAILIMAP_FETCH_ATT_FLAGS,
2649 MAILIMAP_FETCH_ATT_INTERNALDATE, MAILIMAP_FETCH_ATT_RFC822,
2650 MAILIMAP_FETCH_ATT_RFC822_HEADER, MAILIMAP_FETCH_ATT_RFC822_SIZE,
2651 MAILIMAP_FETCH_ATT_RFC822_TEXT, MAILIMAP_FETCH_ATT_BODY,
2652 MAILIMAP_FETCH_ATT_BODYSTRUCTURE, MAILIMAP_FETCH_ATT_UID,
2653 MAILIMAP_FETCH_ATT_BODY_SECTION or MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION
2654
2655 - section is the location of the part to fetch if type is
2656 MAILIMAP_FETCH_ATT_BODY_SECTION or MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION
2657
2658 - offset is the first byte to fetch in the given part
2659
2660 - size is the maximum size of the part to fetch
2661*/
2662
2663struct mailimap_fetch_att {
2664 int att_type;
2665 struct mailimap_section * att_section;
2666 uint32_t att_offset;
2667 uint32_t att_size;
2668};
2669
2670struct mailimap_fetch_att *
2671mailimap_fetch_att_new(int att_type, struct mailimap_section * att_section,
2672 uint32_t att_offset, uint32_t att_size);
2673
2674
2675void mailimap_fetch_att_free(struct mailimap_fetch_att * fetch_att);
2676
2677
2678/* this is the type of a FETCH operation */
2679
2680enum {
2681 MAILIMAP_FETCH_TYPE_ALL, /* equivalent to (FLAGS INTERNALDATE
2682 RFC822.SIZE ENVELOPE) */
2683 MAILIMAP_FETCH_TYPE_FULL, /* equivalent to (FLAGS INTERNALDATE
2684 RFC822.SIZE ENVELOPE BODY) */
2685 MAILIMAP_FETCH_TYPE_FAST, /* equivalent to (FLAGS INTERNALDATE
2686 RFC822.SIZE) */
2687 MAILIMAP_FETCH_TYPE_FETCH_ATT, /* when there is only of fetch
2688 attribute */
2689 MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST, /* when there is a list of fetch
2690 attributes */
2691};
2692
2693/*
2694 mailimap_fetch_type is the description of the FETCH operation
2695
2696 - type can be MAILIMAP_FETCH_TYPE_ALL, MAILIMAP_FETCH_TYPE_FULL,
2697 MAILIMAP_FETCH_TYPE_FAST, MAILIMAP_FETCH_TYPE_FETCH_ATT or
2698 MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST
2699
2700 - fetch_att is a fetch attribute if type is MAILIMAP_FETCH_TYPE_FETCH_ATT
2701
2702 - fetch_att_list is a list of fetch attributes if type is
2703 MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST
2704*/
2705
2706struct mailimap_fetch_type {
2707 int ft_type;
2708 union {
2709 struct mailimap_fetch_att * ft_fetch_att;
2710 clist * ft_fetch_att_list; /* list of (struct mailimap_fetch_att *) */
2711 } ft_data;
2712};
2713
2714struct mailimap_fetch_type *
2715mailimap_fetch_type_new(int ft_type,
2716 struct mailimap_fetch_att * ft_fetch_att,
2717 clist * ft_fetch_att_list);
2718
2719
2720void mailimap_fetch_type_free(struct mailimap_fetch_type * fetch_type);
2721
2722
2723
2724/*
2725 mailimap_store_att_flags is the description of the STORE operation
2726 (change flags of a message)
2727
2728 - sign can be 0 (set flag), +1 (add flag) or -1 (remove flag)
2729
2730 - silent has a value of 1 if the flags are changed with no server
2731 response
2732
2733 - flag_list is the list of flags to change
2734*/
2735
2736struct mailimap_store_att_flags {
2737 int fl_sign;
2738 int fl_silent;
2739 struct mailimap_flag_list * fl_flag_list;
2740};
2741
2742struct mailimap_store_att_flags *
2743mailimap_store_att_flags_new(int fl_sign, int fl_silent,
2744 struct mailimap_flag_list * fl_flag_list);
2745
2746void mailimap_store_att_flags_free(struct mailimap_store_att_flags *
2747 store_att_flags);
2748
2749
2750
2751/* this is the condition of the SEARCH operation */
2752
2753enum {
2754 MAILIMAP_SEARCH_KEY_ALL, /* all messages */
2755 MAILIMAP_SEARCH_KEY_ANSWERED, /* messages with the flag \Answered */
2756 MAILIMAP_SEARCH_KEY_BCC, /* messages whose Bcc field contains the
2757 given string */
2758 MAILIMAP_SEARCH_KEY_BEFORE, /* messages whose internal date is earlier
2759 than the specified date */
2760 MAILIMAP_SEARCH_KEY_BODY, /* message that contains the given string
2761 (in header and text parts) */
2762 MAILIMAP_SEARCH_KEY_CC, /* messages whose Cc field contains the
2763 given string */
2764 MAILIMAP_SEARCH_KEY_DELETED, /* messages with the flag \Deleted */
2765 MAILIMAP_SEARCH_KEY_FLAGGED, /* messages with the flag \Flagged */
2766 MAILIMAP_SEARCH_KEY_FROM, /* messages whose From field contains the
2767 given string */
2768 MAILIMAP_SEARCH_KEY_KEYWORD, /* messages with the flag keyword set */
2769 MAILIMAP_SEARCH_KEY_NEW, /* messages with the flag \Recent and not
2770 the \Seen flag */
2771 MAILIMAP_SEARCH_KEY_OLD, /* messages that do not have the
2772 \Recent flag set */
2773 MAILIMAP_SEARCH_KEY_ON, /* messages whose internal date is the
2774 specified date */
2775 MAILIMAP_SEARCH_KEY_RECENT, /* messages with the flag \Recent */
2776 MAILIMAP_SEARCH_KEY_SEEN, /* messages with the flag \Seen */
2777 MAILIMAP_SEARCH_KEY_SINCE, /* messages whose internal date is later
2778 than specified date */
2779 MAILIMAP_SEARCH_KEY_SUBJECT, /* messages whose Subject field contains the
2780 given string */
2781 MAILIMAP_SEARCH_KEY_TEXT, /* messages whose text part contains the
2782 given string */
2783 MAILIMAP_SEARCH_KEY_TO, /* messages whose To field contains the
2784 given string */
2785 MAILIMAP_SEARCH_KEY_UNANSWERED, /* messages with no flag \Answered */
2786 MAILIMAP_SEARCH_KEY_UNDELETED, /* messages with no flag \Deleted */
2787 MAILIMAP_SEARCH_KEY_UNFLAGGED, /* messages with no flag \Flagged */
2788 MAILIMAP_SEARCH_KEY_UNKEYWORD, /* messages with no flag keyword */
2789 MAILIMAP_SEARCH_KEY_UNSEEN, /* messages with no flag \Seen */
2790 MAILIMAP_SEARCH_KEY_DRAFT, /* messages with no flag \Draft */
2791 MAILIMAP_SEARCH_KEY_HEADER, /* messages whose given field
2792 contains the given string */
2793 MAILIMAP_SEARCH_KEY_LARGER, /* messages whose size is larger then
2794 the given size */
2795 MAILIMAP_SEARCH_KEY_NOT, /* not operation of the condition */
2796 MAILIMAP_SEARCH_KEY_OR, /* or operation between two conditions */
2797 MAILIMAP_SEARCH_KEY_SENTBEFORE, /* messages whose date given in Date header
2798 is earlier than the specified date */
2799 MAILIMAP_SEARCH_KEY_SENTON, /* messages whose date given in Date header
2800 is the specified date */
2801 MAILIMAP_SEARCH_KEY_SENTSINCE, /* messages whose date given in Date header
2802 is later than specified date */
2803 MAILIMAP_SEARCH_KEY_SMALLER, /* messages whose size is smaller than
2804 the given size */
2805 MAILIMAP_SEARCH_KEY_UID, /* messages whose unique identifiers are
2806 in the given range */
2807 MAILIMAP_SEARCH_KEY_UNDRAFT, /* messages with no flag \Draft */
2808 MAILIMAP_SEARCH_KEY_SET, /* messages whose number (or unique
2809 identifiers in case of UID SEARCH) are
2810 in the given range */
2811 MAILIMAP_SEARCH_KEY_MULTIPLE, /* the boolean operator between the
2812 conditions is AND */
2813};
2814
2815/*
2816 mailimap_search_key is the condition on the messages to return
2817
2818 - type is the type of the condition
2819
2820 - bcc is the text to search in the Bcc field when type is
2821 MAILIMAP_SEARCH_KEY_BCC, should be allocated with malloc()
2822
2823 - before is a date when type is MAILIMAP_SEARCH_KEY_BEFORE
2824
2825 - body is the text to search in the message when type is
2826 MAILIMAP_SEARCH_KEY_BODY, should be allocated with malloc()
2827
2828 - cc is the text to search in the Cc field when type is
2829 MAILIMAP_SEARCH_KEY_CC, should be allocated with malloc()
2830
2831 - from is the text to search in the From field when type is
2832 MAILIMAP_SEARCH_KEY_FROM, should be allocated with malloc()
2833
2834 - keyword is the keyword flag name when type is MAILIMAP_SEARCH_KEY_KEYWORD,
2835 should be allocated with malloc()
2836
2837 - on is a date when type is MAILIMAP_SEARCH_KEY_ON
2838
2839 - since is a date when type is MAILIMAP_SEARCH_KEY_SINCE
2840
2841 - subject is the text to search in the Subject field when type is
2842 MAILIMAP_SEARCH_KEY_SUBJECT, should be allocated with malloc()
2843
2844 - text is the text to search in the text part of the message when
2845 type is MAILIMAP_SEARCH_KEY_TEXT, should be allocated with malloc()
2846
2847 - to is the text to search in the To field when type is
2848 MAILIMAP_SEARCH_KEY_TO, should be allocated with malloc()
2849
2850 - unkeyword is the keyword flag name when type is
2851 MAILIMAP_SEARCH_KEY_UNKEYWORD, should be allocated with malloc()
2852
2853 - header_name is the header name when type is MAILIMAP_SEARCH_KEY_HEADER,
2854 should be allocated with malloc()
2855
2856 - header_value is the text to search in the given header when type is
2857 MAILIMAP_SEARCH_KEY_HEADER, should be allocated with malloc()
2858
2859 - larger is a size when type is MAILIMAP_SEARCH_KEY_LARGER
2860
2861 - not is a condition when type is MAILIMAP_SEARCH_KEY_NOT
2862
2863 - or1 is a condition when type is MAILIMAP_SEARCH_KEY_OR
2864
2865 - or2 is a condition when type is MAILIMAP_SEARCH_KEY_OR
2866
2867 - sentbefore is a date when type is MAILIMAP_SEARCH_KEY_SENTBEFORE
2868
2869 - senton is a date when type is MAILIMAP_SEARCH_KEY_SENTON
2870
2871 - sentsince is a date when type is MAILIMAP_SEARCH_KEY_SENTSINCE
2872
2873 - smaller is a size when type is MAILIMAP_SEARCH_KEY_SMALLER
2874
2875 - uid is a set of messages when type is MAILIMAP_SEARCH_KEY_UID
2876
2877 - set is a set of messages when type is MAILIMAP_SEARCH_KEY_SET
2878
2879 - multiple is a set of message when type is MAILIMAP_SEARCH_KEY_MULTIPLE
2880*/
2881
2882struct mailimap_search_key {
2883 int sk_type;
2884 union {
2885 char * sk_bcc;
2886 struct mailimap_date * sk_before;
2887 char * sk_body;
2888 char * sk_cc;
2889 char * sk_from;
2890 char * sk_keyword;
2891 struct mailimap_date * sk_on;
2892 struct mailimap_date * sk_since;
2893 char * sk_subject;
2894 char * sk_text;
2895 char * sk_to;
2896 char * sk_unkeyword;
2897 struct {
2898 char * sk_header_name;
2899 char * sk_header_value;
2900 } sk_header;
2901 uint32_t sk_larger;
2902 struct mailimap_search_key * sk_not;
2903 struct {
2904 struct mailimap_search_key * sk_or1;
2905 struct mailimap_search_key * sk_or2;
2906 } sk_or;
2907 struct mailimap_date * sk_sentbefore;
2908 struct mailimap_date * sk_senton;
2909 struct mailimap_date * sk_sentsince;
2910 uint32_t sk_smaller;
2911 struct mailimap_set * sk_uid;
2912 struct mailimap_set * sk_set;
2913 clist * sk_multiple; /* list of (struct mailimap_search_key *) */
2914 } sk_data;
2915};
2916
2917struct mailimap_search_key *
2918mailimap_search_key_new(int sk_type,
2919 char * sk_bcc, struct mailimap_date * sk_before, char * sk_body,
2920 char * sk_cc, char * sk_from, char * sk_keyword,
2921 struct mailimap_date * sk_on, struct mailimap_date * sk_since,
2922 char * sk_subject, char * sk_text, char * sk_to,
2923 char * sk_unkeyword, char * sk_header_name,
2924 char * sk_header_value, uint32_t sk_larger,
2925 struct mailimap_search_key * sk_not,
2926 struct mailimap_search_key * sk_or1,
2927 struct mailimap_search_key * sk_or2,
2928 struct mailimap_date * sk_sentbefore,
2929 struct mailimap_date * sk_senton,
2930 struct mailimap_date * sk_sentsince,
2931 uint32_t sk_smaller, struct mailimap_set * sk_uid,
2932 struct mailimap_set * sk_set, clist * sk_multiple);
2933
2934
2935void mailimap_search_key_free(struct mailimap_search_key * key);
2936
2937
2938/*
2939 mailimap_status_att_list is a list of mailbox STATUS request type
2940
2941 - list is a list of mailbox STATUS request type
2942 (value of elements in the list can be MAILIMAP_STATUS_ATT_MESSAGES,
2943 MAILIMAP_STATUS_ATT_RECENT, MAILIMAP_STATUS_ATT_UIDNEXT,
2944 MAILIMAP_STATUS_ATT_UIDVALIDITY or MAILIMAP_STATUS_ATT_UNSEEN),
2945 each element should be allocated with malloc()
2946*/
2947
2948struct mailimap_status_att_list {
2949 clist * att_list; /* list of (uint32_t *) */
2950};
2951
2952struct mailimap_status_att_list *
2953mailimap_status_att_list_new(clist * att_list);
2954
2955void mailimap_status_att_list_free(struct mailimap_status_att_list *
2956 status_att_list);
2957
2958
2959
2960
2961/* internal use functions */
2962
2963
2964uint32_t * mailimap_number_alloc_new(uint32_t number);
2965
2966void mailimap_number_alloc_free(uint32_t * pnumber);
2967
2968
2969void mailimap_addr_host_free(char * addr_host);
2970
2971void mailimap_addr_mailbox_free(char * addr_mailbox);
2972
2973void mailimap_addr_adl_free(char * addr_adl);
2974
2975void mailimap_addr_name_free(char * addr_name);
2976
2977void mailimap_astring_free(char * astring);
2978
2979void mailimap_atom_free(char * atom);
2980
2981void mailimap_auth_type_free(char * auth_type);
2982
2983void mailimap_base64_free(char * base64);
2984
2985void mailimap_body_fld_desc_free(char * body_fld_desc);
2986
2987void mailimap_body_fld_id_free(char * body_fld_id);
2988
2989void mailimap_body_fld_md5_free(char * body_fld_md5);
2990
2991void mailimap_env_date_free(char * date);
2992
2993void mailimap_env_in_reply_to_free(char * in_reply_to);
2994
2995void mailimap_env_message_id_free(char * message_id);
2996
2997void mailimap_env_subject_free(char * subject);
2998
2999void mailimap_flag_extension_free(char * flag_extension);
3000
3001void mailimap_flag_keyword_free(char * flag_keyword);
3002
3003void
3004mailimap_header_fld_name_free(char * header_fld_name);
3005
3006void mailimap_literal_free(char * literal);
3007
3008void mailimap_mailbox_free(char * mailbox);
3009
3010void
3011mailimap_mailbox_data_search_free(clist * data_search);
3012
3013void mailimap_media_subtype_free(char * media_subtype);
3014
3015void mailimap_media_text_free(char * media_text);
3016
3017void mailimap_msg_att_envelope_free(struct mailimap_envelope * env);
3018
3019void
3020mailimap_msg_att_internaldate_free(struct mailimap_date_time * date_time);
3021
3022void
3023mailimap_msg_att_rfc822_free(char * str);
3024
3025void
3026mailimap_msg_att_rfc822_header_free(char * str);
3027
3028void
3029mailimap_msg_att_rfc822_text_free(char * str);
3030
3031void
3032mailimap_msg_att_body_free(struct mailimap_body * body);
3033
3034void
3035mailimap_msg_att_bodystructure_free(struct mailimap_body * body);
3036
3037void mailimap_nstring_free(char * str);
3038
3039void
3040mailimap_string_free(char * str);
3041
3042void mailimap_tag_free(char * tag);
3043
3044void mailimap_text_free(char * text);
3045
3046
3047
3048
3049
3050/* IMAP connection */
3051
3052/* this is the state of the IMAP connection */
3053
3054enum {
3055 MAILIMAP_STATE_DISCONNECTED,
3056 MAILIMAP_STATE_NON_AUTHENTICATED,
3057 MAILIMAP_STATE_AUTHENTICATED,
3058 MAILIMAP_STATE_SELECTED,
3059 MAILIMAP_STATE_LOGOUT
3060};
3061
3062/*
3063 mailimap is an IMAP connection
3064
3065 - response is a human readable message returned with a reponse,
3066 must be accessed read-only
3067
3068 - stream is the connection with the IMAP server
3069
3070 - stream_buffer is the buffer where the data to parse are stored
3071
3072 - state is the state of IMAP connection
3073
3074 - tag is the current tag being used in IMAP connection
3075
3076 - response_buffer is the buffer for response messages
3077
3078 - connection_info is the information returned in response
3079 for the last command about the connection
3080
3081 - selection_info is the information returned in response
3082 for the last command about the current selected mailbox
3083
3084 - response_info is the other information returned in response
3085 for the last command
3086*/
3087
3088struct mailimap {
3089 char * imap_response;
3090
3091 /* internals */
3092 mailstream * imap_stream;
3093
3094 size_t imap_progr_rate;
3095 progress_function * imap_progr_fun;
3096
3097 MMAPString * imap_stream_buffer;
3098 MMAPString * imap_response_buffer;
3099
3100 int imap_state;
3101 int imap_tag;
3102
3103 struct mailimap_connection_info * imap_connection_info;
3104 struct mailimap_selection_info * imap_selection_info;
3105 struct mailimap_response_info * imap_response_info;
3106};
3107
3108typedef struct mailimap mailimap;
3109
3110
3111/*
3112 mailimap_connection_info is the information about the connection
3113
3114 - capability is the list of capability of the IMAP server
3115*/
3116
3117struct mailimap_connection_info {
3118 struct mailimap_capability_data * imap_capability;
3119};
3120
3121struct mailimap_connection_info *
3122mailimap_connection_info_new(void);
3123
3124void
3125mailimap_connection_info_free(struct mailimap_connection_info * conn_info);
3126
3127
3128/* this is the type of mailbox access */
3129
3130enum {
3131 MAILIMAP_MAILBOX_READONLY,
3132 MAILIMAP_MAILBOX_READWRITE
3133};
3134
3135/*
3136 mailimap_selection_info is information about the current selected mailbox
3137
3138 - perm_flags is a list of flags that can be changed permanently on the
3139 messages of the mailbox
3140
3141 - perm is the access on the mailbox, value can be
3142 MAILIMAP_MAILBOX_READONLY or MAILIMAP_MAILBOX_READWRITE
3143
3144 - uidnext is the next unique identifier
3145
3146 - uidvalidity is the unique identifiers validity
3147
3148 - first_unseen is the number of the first unseen message
3149
3150 - flags is a list of flags that can be used on the messages of
3151 the mailbox
3152
3153 - exists is the number of messages in the mailbox
3154
3155 - recent is the number of recent messages in the mailbox
3156
3157 - unseen is the number of unseen messages in the mailbox
3158*/
3159
3160struct mailimap_selection_info {
3161 clist * sel_perm_flags; /* list of (struct flag_perm *) */
3162 int sel_perm;
3163 uint32_t sel_uidnext;
3164 uint32_t sel_uidvalidity;
3165 uint32_t sel_first_unseen;
3166 struct mailimap_flag_list * sel_flags;
3167 uint32_t sel_exists;
3168 uint32_t sel_recent;
3169 uint32_t sel_unseen;
3170};
3171
3172struct mailimap_selection_info *
3173mailimap_selection_info_new(void);
3174
3175void
3176mailimap_selection_info_free(struct mailimap_selection_info * sel_info);
3177
3178
3179/*
3180 mailimap_response_info is the other information returned in the
3181 response for a command
3182
3183 - alert is the human readable text returned with ALERT response
3184
3185 - parse is the human readable text returned with PARSE response
3186
3187 - badcharset is a list of charset returned with a BADCHARSET response
3188
3189 - trycreate is set to 1 if a trycreate response was returned
3190
3191 - mailbox_list is a list of mailboxes
3192
3193 - mailbox_lsub is a list of subscribed mailboxes
3194
3195 - search_result is a list of message numbers or unique identifiers
3196
3197 - status is a STATUS response
3198
3199 - expunged is a list of message numbers
3200
3201 - fetch_list is a list of fetch response
3202*/
3203
3204struct mailimap_response_info {
3205 char * rsp_alert;
3206 char * rsp_parse;
3207 clist * rsp_badcharset; /* list of (char *) */
3208 int rsp_trycreate;
3209 clist * rsp_mailbox_list; /* list of (struct mailimap_mailbox_list *) */
3210 clist * rsp_mailbox_lsub; /* list of (struct mailimap_mailbox_list *) */
3211 clist * rsp_search_result; /* list of (uint32_t *) */
3212 struct mailimap_mailbox_data_status * rsp_status;
3213 clist * rsp_expunged; /* list of (uint32_t 32 *) */
3214 clist * rsp_fetch_list; /* list of (struct mailimap_msg_att *) */
3215};
3216
3217struct mailimap_response_info *
3218mailimap_response_info_new(void);
3219
3220void
3221mailimap_response_info_free(struct mailimap_response_info * resp_info);
3222
3223
3224/* these are the possible returned error codes */
3225
3226enum {
3227 MAILIMAP_NO_ERROR = 0,
3228 MAILIMAP_NO_ERROR_AUTHENTICATED = 1,
3229 MAILIMAP_NO_ERROR_NON_AUTHENTICATED = 2,
3230 MAILIMAP_ERROR_BAD_STATE,
3231 MAILIMAP_ERROR_STREAM,
3232 MAILIMAP_ERROR_PARSE,
3233 MAILIMAP_ERROR_CONNECTION_REFUSED,
3234 MAILIMAP_ERROR_MEMORY,
3235 MAILIMAP_ERROR_FATAL,
3236 MAILIMAP_ERROR_PROTOCOL,
3237 MAILIMAP_ERROR_DONT_ACCEPT_CONNECTION,
3238 MAILIMAP_ERROR_APPEND,
3239 MAILIMAP_ERROR_NOOP,
3240 MAILIMAP_ERROR_LOGOUT,
3241 MAILIMAP_ERROR_CAPABILITY,
3242 MAILIMAP_ERROR_CHECK,
3243 MAILIMAP_ERROR_CLOSE,
3244 MAILIMAP_ERROR_EXPUNGE,
3245 MAILIMAP_ERROR_COPY,
3246 MAILIMAP_ERROR_UID_COPY,
3247 MAILIMAP_ERROR_CREATE,
3248 MAILIMAP_ERROR_DELETE,
3249 MAILIMAP_ERROR_EXAMINE,
3250 MAILIMAP_ERROR_FETCH,
3251 MAILIMAP_ERROR_UID_FETCH,
3252 MAILIMAP_ERROR_LIST,
3253 MAILIMAP_ERROR_LOGIN,
3254 MAILIMAP_ERROR_LSUB,
3255 MAILIMAP_ERROR_RENAME,
3256 MAILIMAP_ERROR_SEARCH,
3257 MAILIMAP_ERROR_UID_SEARCH,
3258 MAILIMAP_ERROR_SELECT,
3259 MAILIMAP_ERROR_STATUS,
3260 MAILIMAP_ERROR_STORE,
3261 MAILIMAP_ERROR_UID_STORE,
3262 MAILIMAP_ERROR_SUBSCRIBE,
3263 MAILIMAP_ERROR_UNSUBSCRIBE,
3264 MAILIMAP_ERROR_STARTTLS,
3265 MAILIMAP_ERROR_INVAL,
3266};
3267
3268
3269#ifdef __cplusplus
3270}
3271#endif
3272
3273#endif
3274
diff --git a/kmicromail/libetpan/imap/mailimap_types_helper.c b/kmicromail/libetpan/imap/mailimap_types_helper.c
new file mode 100644
index 0000000..8fe273e
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_types_helper.c
@@ -0,0 +1,1269 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimap_types.h"
37#include "mail.h"
38
39#include <stdlib.h>
40
41/* ************************************************************************* */
42/* ************************************************************************* */
43/* ************************************************************************* */
44/* ************************************************************************* */
45/* ************************************************************************* */
46/* ************************************************************************* */
47
48/* in helper */
49
50
51
52
53struct mailimap_set_item * mailimap_set_item_new_single(uint32_t index)
54{
55 return mailimap_set_item_new(index, index);
56}
57
58struct mailimap_set *
59mailimap_set_new_single_item(struct mailimap_set_item * item)
60{
61 struct mailimap_set * set;
62 clist * list;
63 int r;
64
65 list = clist_new();
66 if (list == NULL)
67 return NULL;
68
69 r = clist_append(list, item);
70 if (r < 0) {
71 clist_free(list);
72 return NULL;
73 }
74
75 set = mailimap_set_new(list);
76 if (set == NULL) {
77 clist_free(list);
78 return NULL;
79 }
80
81 return set;
82}
83
84struct mailimap_set * mailimap_set_new_interval(uint32_t first, uint32_t last)
85{
86 struct mailimap_set_item * item;
87 struct mailimap_set * set;
88
89 item = mailimap_set_item_new(first, last);
90 if (item == NULL)
91 return NULL;
92
93 set = mailimap_set_new_single_item(item);
94 if (set == NULL) {
95 mailimap_set_item_free(item);
96 return NULL;
97 }
98
99 return set;
100}
101
102struct mailimap_set * mailimap_set_new_single(uint32_t index)
103{
104 return mailimap_set_new_interval(index, index);
105}
106
107
108struct mailimap_set * mailimap_set_new_empty(void)
109{
110 clist * list;
111
112 list = clist_new();
113 if (list == NULL)
114 return NULL;
115
116 return mailimap_set_new(list);
117}
118
119int mailimap_set_add(struct mailimap_set * set,
120 struct mailimap_set_item * set_item)
121{
122 int r;
123
124 r = clist_append(set->set_list, set_item);
125 if (r < 0)
126 return MAILIMAP_ERROR_MEMORY;
127
128 return MAILIMAP_NO_ERROR;
129}
130
131int mailimap_set_add_interval(struct mailimap_set * set,
132 uint32_t first, uint32_t last)
133{
134 struct mailimap_set_item * item;
135 int r;
136
137 item = mailimap_set_item_new(first, last);
138 if (item == NULL)
139 return MAILIMAP_ERROR_MEMORY;
140
141 r = mailimap_set_add(set, item);
142 if (r != MAILIMAP_NO_ERROR) {
143 mailimap_set_item_free(item);
144 return r;
145 }
146 else
147 return MAILIMAP_NO_ERROR;
148}
149
150int mailimap_set_add_single(struct mailimap_set * set,
151 uint32_t index)
152{
153 return mailimap_set_add_interval(set, index, index);
154}
155
156/* CHECK */
157/* no args */
158
159/* CLOSE */
160/* no args */
161
162/* EXPUNGE */
163/* no args */
164
165/* COPY */
166/* set and gchar */
167
168/* FETCH */
169/* set and gchar fetch_type */
170
171
172
173/* section */
174
175#if 0
176/* not correct XXX */
177
178struct mailimap_section * mailimap_section_new_empty(void)
179{
180 clist * list;
181
182 list = clist_new();
183 if (list == NULL)
184 return NULL;
185
186 return mailimap_section_new(list);
187}
188#endif
189
190static struct mailimap_section *
191mailimap_section_new_msgtext(struct mailimap_section_msgtext * msgtext)
192{
193 struct mailimap_section_spec * spec;
194 struct mailimap_section * section;
195
196 spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT,
197 msgtext, NULL, NULL);
198 if (spec == NULL)
199 return NULL;
200
201 section = mailimap_section_new(spec);
202 if (section == NULL) {
203 /* detach section_msgtext so that it will not be freed */
204 spec->sec_data.sec_msgtext = NULL;
205 mailimap_section_spec_free(spec);
206 return NULL;
207 }
208
209 return section;
210}
211
212static struct mailimap_section *
213mailimap_section_new_part_msgtext(struct mailimap_section_part * part,
214 struct mailimap_section_msgtext * msgtext)
215{
216 struct mailimap_section_spec * spec;
217 struct mailimap_section * section;
218 struct mailimap_section_text * text;
219
220 text = mailimap_section_text_new(MAILIMAP_SECTION_TEXT_SECTION_MSGTEXT,
221 msgtext);
222 if (text == NULL)
223 return NULL;
224
225 spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART,
226 NULL, part, text);
227 if (spec == NULL) {
228 /* detach section_msgtext so that it will not be freed */
229 text->sec_msgtext = NULL;
230 mailimap_section_text_free(text);
231 return NULL;
232 }
233
234 section = mailimap_section_new(spec);
235 if (section == NULL) {
236 /* detach section_msgtext so that it will not be freed */
237 text->sec_msgtext = NULL;
238 mailimap_section_spec_free(spec);
239 return NULL;
240 }
241
242 return section;
243}
244
245/*
246HEADER
247HEADER.FIELDS fields
248HEADER.FIELDS.NOT fields
249TEXT
250*/
251
252struct mailimap_section * mailimap_section_new_header(void)
253{
254 struct mailimap_section_msgtext * msgtext;
255 struct mailimap_section * section;
256
257 msgtext = mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER,
258 NULL);
259 if (msgtext == NULL)
260 return NULL;
261
262 section = mailimap_section_new_msgtext(msgtext);
263 if (section == NULL) {
264 mailimap_section_msgtext_free(msgtext);
265 return NULL;
266 }
267
268 return section;
269}
270
271struct mailimap_section *
272mailimap_section_new_header_fields(struct mailimap_header_list * header_list)
273{
274 struct mailimap_section * section;
275 struct mailimap_section_msgtext * msgtext;
276
277 msgtext =
278 mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS,
279 header_list);
280 if (msgtext == NULL)
281 return NULL;
282
283 section = mailimap_section_new_msgtext(msgtext);
284 if (section == NULL) {
285 /* detach header_list so that it will not be freed */
286 msgtext->sec_header_list = NULL;
287 mailimap_section_msgtext_free(msgtext);
288 return NULL;
289 }
290
291 return section;
292}
293
294struct mailimap_section *
295mailimap_section_new_header_fields_not(struct mailimap_header_list * header_list)
296{
297 struct mailimap_section * section;
298 struct mailimap_section_msgtext * msgtext;
299
300 msgtext =
301 mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT,
302 header_list);
303 if (msgtext == NULL)
304 return NULL;
305
306 section = mailimap_section_new_msgtext(msgtext);
307 if (section == NULL) {
308 /* detach header_list so that it will not be freed */
309 msgtext->sec_header_list = NULL;
310 mailimap_section_msgtext_free(msgtext);
311 return NULL;
312 }
313
314 return section;
315}
316
317struct mailimap_section * mailimap_section_new_text(void)
318{
319 struct mailimap_section * section;
320 struct mailimap_section_msgtext * msgtext;
321
322 msgtext = mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_TEXT, NULL);
323 if (msgtext == NULL)
324 return NULL;
325
326 section = mailimap_section_new_msgtext(msgtext);
327 if (section == NULL) {
328 mailimap_section_msgtext_free(msgtext);
329 return NULL;
330 }
331
332 return section;
333}
334
335/*
336section-part
337section-part . MIME
338section-part . HEADER
339section-part . HEADER.FIELDS fields
340section-part . HEADER.FIELDS.NOT fields
341section-part . TEXT
342*/
343
344struct mailimap_section *
345mailimap_section_new_part(struct mailimap_section_part * part)
346{
347 struct mailimap_section_spec * spec;
348 struct mailimap_section * section;
349
350 spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART,
351 NULL, part, NULL);
352 if (spec == NULL)
353 return NULL;
354
355 section = mailimap_section_new(spec);
356 if (section == NULL) {
357 /* detach section_part so that it will not be freed */
358 spec->sec_data.sec_part = NULL;
359 mailimap_section_spec_free(spec);
360 return NULL;
361 }
362
363 return section;
364}
365
366struct mailimap_section *
367mailimap_section_new_part_mime(struct mailimap_section_part * part)
368{
369 struct mailimap_section_spec * spec;
370 struct mailimap_section * section;
371 struct mailimap_section_text * text;
372
373 text = mailimap_section_text_new(MAILIMAP_SECTION_TEXT_MIME, NULL);
374 if (text == NULL)
375 return NULL;
376
377 spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART,
378 NULL, part, text);
379 if (spec == NULL) {
380 mailimap_section_text_free(text);
381 return NULL;
382 }
383
384 section = mailimap_section_new(spec);
385 if (section == NULL) {
386 /* detach section_part so that it will not be freed */
387 spec->sec_data.sec_part = NULL;
388 mailimap_section_spec_free(spec);
389 return NULL;
390 }
391
392 return section;
393}
394
395struct mailimap_section *
396mailimap_section_new_part_header(struct mailimap_section_part * part)
397{
398 struct mailimap_section_msgtext * msgtext;
399 struct mailimap_section * section;
400
401 msgtext = mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER,
402 NULL);
403 if (msgtext == NULL)
404 return NULL;
405
406 section = mailimap_section_new_part_msgtext(part, msgtext);
407 if (section == NULL) {
408 mailimap_section_msgtext_free(msgtext);
409 return NULL;
410 }
411
412 return section;
413}
414
415struct mailimap_section *
416mailimap_section_new_part_header_fields(struct mailimap_section_part *
417 part,
418 struct mailimap_header_list *
419 header_list)
420{
421 struct mailimap_section * section;
422 struct mailimap_section_msgtext * msgtext;
423
424 msgtext =
425 mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS,
426 header_list);
427 if (msgtext == NULL)
428 return NULL;
429
430 section = mailimap_section_new_part_msgtext(part, msgtext);
431 if (section == NULL) {
432 /* detach header_list so that it will not be freed */
433 msgtext->sec_header_list = NULL;
434 mailimap_section_msgtext_free(msgtext);
435 return NULL;
436 }
437
438 return section;
439}
440
441struct mailimap_section *
442mailimap_section_new_part_header_fields_not(struct mailimap_section_part
443 * part,
444 struct mailimap_header_list
445 * header_list)
446{
447 struct mailimap_section * section;
448 struct mailimap_section_msgtext * msgtext;
449
450 msgtext =
451 mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT,
452 header_list);
453 if (msgtext == NULL)
454 return NULL;
455
456 section = mailimap_section_new_part_msgtext(part, msgtext);
457 if (section == NULL) {
458 /* detach header_list so that it will not be freed */
459 msgtext->sec_header_list = NULL;
460 mailimap_section_msgtext_free(msgtext);
461 return NULL;
462 }
463
464 return section;
465}
466
467struct mailimap_section *
468mailimap_section_new_part_text(struct mailimap_section_part * part)
469{
470 struct mailimap_section * section;
471 struct mailimap_section_msgtext * msgtext;
472
473 msgtext = mailimap_section_msgtext_new(MAILIMAP_SECTION_MSGTEXT_TEXT, NULL);
474 if (msgtext == NULL)
475 return NULL;
476
477 section = mailimap_section_new_part_msgtext(part, msgtext);
478 if (section == NULL) {
479 mailimap_section_msgtext_free(msgtext);
480 return NULL;
481 }
482
483 return section;
484}
485
486/* end of section */
487
488
489
490
491
492
493struct mailimap_fetch_att *
494mailimap_fetch_att_new_envelope(void)
495{
496 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_ENVELOPE, NULL, 0, 0);
497}
498
499struct mailimap_fetch_att *
500mailimap_fetch_att_new_flags(void)
501{
502 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_FLAGS, NULL, 0, 0);
503}
504
505struct mailimap_fetch_att *
506mailimap_fetch_att_new_internaldate(void)
507{
508 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_INTERNALDATE, NULL, 0, 0);
509}
510
511struct mailimap_fetch_att *
512mailimap_fetch_att_new_rfc822(void)
513{
514 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_RFC822, NULL, 0, 0);
515}
516
517struct mailimap_fetch_att *
518mailimap_fetch_att_new_rfc822_header(void)
519{
520 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_RFC822_HEADER, NULL, 0, 0);
521}
522
523struct mailimap_fetch_att *
524mailimap_fetch_att_new_rfc822_size(void)
525{
526 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_RFC822_SIZE, NULL, 0, 0);
527}
528
529struct mailimap_fetch_att *
530mailimap_fetch_att_new_rfc822_text(void)
531{
532 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_RFC822_TEXT, NULL, 0, 0);
533}
534
535struct mailimap_fetch_att *
536mailimap_fetch_att_new_body(void)
537{
538 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODY, NULL, 0, 0);
539}
540
541struct mailimap_fetch_att *
542mailimap_fetch_att_new_bodystructure(void)
543{
544 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODYSTRUCTURE, NULL, 0, 0);
545}
546
547struct mailimap_fetch_att *
548mailimap_fetch_att_new_uid(void)
549{
550 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_UID, NULL, 0, 0);
551}
552
553struct mailimap_fetch_att *
554mailimap_fetch_att_new_body_section(struct mailimap_section * section)
555{
556 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODY_SECTION, section, 0, 0);
557}
558
559struct mailimap_fetch_att *
560mailimap_fetch_att_new_body_peek_section(struct mailimap_section * section)
561{
562 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION, section, 0, 0);
563}
564
565struct mailimap_fetch_att *
566mailimap_fetch_att_new_body_section_partial(struct mailimap_section * section,
567 uint32_t offset, uint32_t size)
568{
569 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODY_SECTION, section,
570 offset, size);
571}
572
573struct mailimap_fetch_att *
574mailimap_fetch_att_new_body_peek_section_partial(struct mailimap_section * section,
575 uint32_t offset, uint32_t size)
576{
577 return mailimap_fetch_att_new(MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION, section,
578 offset, size);
579}
580
581
582
583struct mailimap_fetch_type *
584mailimap_fetch_type_new_all(void)
585{
586 return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_ALL, NULL, NULL);
587}
588
589struct mailimap_fetch_type *
590mailimap_fetch_type_new_full(void)
591{
592 return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_FULL, NULL, NULL);
593}
594
595struct mailimap_fetch_type *
596mailimap_fetch_type_new_fast(void)
597{
598 return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_FAST, NULL, NULL);
599}
600
601struct mailimap_fetch_type *
602mailimap_fetch_type_new_fetch_att(struct mailimap_fetch_att * fetch_att)
603{
604 return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_FETCH_ATT, fetch_att, NULL);
605}
606
607struct mailimap_fetch_type *
608mailimap_fetch_type_new_fetch_att_list(clist * fetch_att_list)
609{
610 return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST,
611 NULL, fetch_att_list);
612}
613
614struct mailimap_fetch_type *
615mailimap_fetch_type_new_fetch_att_list_empty(void)
616{
617 clist * list;
618
619 list = clist_new();
620 if (list == NULL)
621 return NULL;
622
623 return mailimap_fetch_type_new(MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST,
624 NULL, list);
625}
626
627int
628mailimap_fetch_type_new_fetch_att_list_add(struct mailimap_fetch_type *
629 fetch_type,
630 struct mailimap_fetch_att * fetch_att)
631{
632 int r;
633
634 r = clist_append(fetch_type->ft_data.ft_fetch_att_list, fetch_att);
635 if (r < 0)
636 return MAILIMAP_ERROR_MEMORY;
637
638 return MAILIMAP_NO_ERROR;
639}
640
641
642
643/* STORE */
644/* set and store_att_flags */
645
646struct mailimap_store_att_flags *
647mailimap_store_att_flags_new_set_flags(struct mailimap_flag_list * flags)
648{
649 return mailimap_store_att_flags_new(0, FALSE, flags);
650}
651
652struct mailimap_store_att_flags *
653mailimap_store_att_flags_new_set_flags_silent(struct mailimap_flag_list *
654 flags)
655{
656 return mailimap_store_att_flags_new(0, TRUE, flags);
657}
658
659struct mailimap_store_att_flags *
660mailimap_store_att_flags_new_add_flags(struct mailimap_flag_list * flags)
661{
662 return mailimap_store_att_flags_new(1, FALSE, flags);
663}
664
665struct mailimap_store_att_flags *
666mailimap_store_att_flags_new_add_flags_silent(struct mailimap_flag_list *
667 flags)
668{
669 return mailimap_store_att_flags_new(1, TRUE, flags);
670}
671
672struct mailimap_store_att_flags *
673mailimap_store_att_flags_new_remove_flags(struct mailimap_flag_list * flags)
674{
675 return mailimap_store_att_flags_new(-1, FALSE, flags);
676}
677
678struct mailimap_store_att_flags *
679mailimap_store_att_flags_new_remove_flags_silent(struct mailimap_flag_list *
680 flags)
681{
682 return mailimap_store_att_flags_new(-1, TRUE, flags);
683}
684
685/* SEARCH */
686/* date search-key set */
687
688/*
689 return mailimap_search_key_new(type, bcc, before,
690 body, cc, from, keyword, on, since,
691 subject, text, to, unkeyword, header_name,
692 header_value, larger, not,
693 or1, or2, sentbefore, senton, sentsince,
694 smaller, uid, set, multiple);
695*/
696
697struct mailimap_search_key *
698mailimap_search_key_new_all(void)
699{
700 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_ALL, NULL, NULL,
701 NULL, NULL, NULL, NULL, NULL, NULL,
702 NULL, NULL, NULL, NULL, NULL,
703 NULL, 0, NULL,
704 NULL, NULL, NULL, NULL, NULL,
705 0, NULL, NULL, NULL);
706}
707
708struct mailimap_search_key *
709mailimap_search_key_new_bcc(char * sk_bcc)
710{
711 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_BCC, sk_bcc, NULL,
712 NULL, NULL, NULL, NULL, NULL, NULL,
713 NULL, NULL, NULL, NULL, NULL,
714 NULL, 0, NULL,
715 NULL, NULL, NULL, NULL, NULL,
716 0, NULL, NULL, NULL);
717}
718
719struct mailimap_search_key *
720mailimap_search_key_new_before(struct mailimap_date * sk_before)
721{
722 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_BEFORE, NULL, sk_before,
723 NULL, NULL, NULL, NULL, NULL, NULL,
724 NULL, NULL, NULL, NULL, NULL,
725 NULL, 0, NULL,
726 NULL, NULL, NULL, NULL, NULL,
727 0, NULL, NULL, NULL);
728}
729
730struct mailimap_search_key *
731mailimap_search_key_new_body(char * sk_body)
732{
733 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_BODY, NULL, NULL,
734 sk_body, NULL, NULL, NULL, NULL, NULL,
735 NULL, NULL, NULL, NULL, NULL,
736 NULL, 0, NULL,
737 NULL, NULL, NULL, NULL, NULL,
738 0, NULL, NULL, NULL);
739}
740
741struct mailimap_search_key *
742mailimap_search_key_new_cc(char * sk_cc)
743{
744 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_CC, NULL, NULL,
745 NULL, sk_cc, NULL, NULL, NULL, NULL,
746 NULL, NULL, NULL, NULL, NULL,
747 NULL, 0, NULL,
748 NULL, NULL, NULL, NULL, NULL,
749 0, NULL, NULL, NULL);
750}
751
752struct mailimap_search_key *
753mailimap_search_key_new_from(char * sk_from)
754{
755 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_FROM, NULL, NULL,
756 NULL, NULL, sk_from, NULL, NULL, NULL,
757 NULL, NULL, NULL, NULL, NULL,
758 NULL, 0, NULL,
759 NULL, NULL, NULL, NULL, NULL,
760 0, NULL, NULL, NULL);
761}
762
763struct mailimap_search_key *
764mailimap_search_key_new_keyword(char * sk_keyword)
765{
766 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_FROM, NULL, NULL,
767 NULL, NULL, NULL, sk_keyword, NULL, NULL,
768 NULL, NULL, NULL, NULL, NULL,
769 NULL, 0, NULL,
770 NULL, NULL, NULL, NULL, NULL,
771 0, NULL, NULL, NULL);
772}
773
774struct mailimap_search_key *
775mailimap_search_key_new_on(struct mailimap_date * sk_on)
776{
777 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_ON, NULL, NULL,
778 NULL, NULL, NULL, NULL, sk_on, NULL,
779 NULL, NULL, NULL, NULL, NULL,
780 NULL, 0, NULL,
781 NULL, NULL, NULL, NULL, NULL,
782 0, NULL, NULL, NULL);
783}
784
785struct mailimap_search_key *
786mailimap_search_key_new_since(struct mailimap_date * sk_since)
787{
788 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SINCE, NULL, NULL,
789 NULL, NULL, NULL, NULL, NULL, sk_since,
790 NULL, NULL, NULL, NULL, NULL,
791 NULL, 0, NULL,
792 NULL, NULL, NULL, NULL, NULL,
793 0, NULL, NULL, NULL);
794}
795
796struct mailimap_search_key *
797mailimap_search_key_new_subject(char * sk_subject)
798{
799 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SINCE, NULL, NULL,
800 NULL, NULL, NULL, NULL, NULL, NULL,
801 sk_subject, NULL, NULL, NULL, NULL,
802 NULL, 0, NULL,
803 NULL, NULL, NULL, NULL, NULL,
804 0, NULL, NULL, NULL);
805}
806
807struct mailimap_search_key *
808mailimap_search_key_new_text(char * sk_text)
809{
810 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_TEXT, NULL, NULL,
811 NULL, NULL, NULL, NULL, NULL, NULL,
812 NULL, sk_text, NULL, NULL, NULL,
813 NULL, 0, NULL,
814 NULL, NULL, NULL, NULL, NULL,
815 0, NULL, NULL, NULL);
816}
817
818struct mailimap_search_key *
819mailimap_search_key_new_to(char * sk_to)
820{
821 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_TO, NULL, NULL,
822 NULL, NULL, NULL, NULL, NULL, NULL,
823 NULL, NULL, sk_to, NULL, NULL,
824 NULL, 0, NULL,
825 NULL, NULL, NULL, NULL, NULL,
826 0, NULL, NULL, NULL);
827}
828
829struct mailimap_search_key *
830mailimap_search_key_new_unkeyword(char * sk_unkeyword)
831{
832 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_UNKEYWORD, NULL, NULL,
833 NULL, NULL, NULL, NULL, NULL, NULL,
834 NULL, NULL, NULL, sk_unkeyword, NULL,
835 NULL, 0, NULL,
836 NULL, NULL, NULL, NULL, NULL,
837 0, NULL, NULL, NULL);
838}
839
840struct mailimap_search_key *
841mailimap_search_key_new_header(char * sk_header_name, char * sk_header_value)
842{
843 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_HEADER, NULL, NULL,
844 NULL, NULL, NULL, NULL, NULL, NULL,
845 NULL, NULL, NULL, NULL, sk_header_name,
846 sk_header_value, 0, NULL,
847 NULL, NULL, NULL, NULL, NULL,
848 0, NULL, NULL, NULL);
849}
850
851struct mailimap_search_key *
852mailimap_search_key_new_larger(uint32_t sk_larger)
853{
854 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_LARGER, NULL, NULL,
855 NULL, NULL, NULL, NULL, NULL, NULL,
856 NULL, NULL, NULL, NULL, NULL,
857 NULL, sk_larger, NULL,
858 NULL, NULL, NULL, NULL, NULL,
859 0, NULL, NULL, NULL);
860}
861
862struct mailimap_search_key *
863mailimap_search_key_new_not(struct mailimap_search_key * sk_not)
864{
865 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_NOT, NULL, NULL,
866 NULL, NULL, NULL, NULL, NULL, NULL,
867 NULL, NULL, NULL, NULL, NULL,
868 NULL, 0, sk_not,
869 NULL, NULL, NULL, NULL, NULL,
870 0, NULL, NULL, NULL);
871}
872
873struct mailimap_search_key *
874mailimap_search_key_new_or(struct mailimap_search_key * sk_or1,
875 struct mailimap_search_key * sk_or2)
876{
877 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_OR, NULL, NULL,
878 NULL, NULL, NULL, NULL, NULL, NULL,
879 NULL, NULL, NULL, NULL, NULL,
880 NULL, 0, NULL,
881 sk_or1, sk_or2, NULL, NULL, NULL,
882 0, NULL, NULL, NULL);
883}
884
885struct mailimap_search_key *
886mailimap_search_key_new_sentbefore(struct mailimap_date * sk_sentbefore)
887{
888 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_NOT, NULL, NULL,
889 NULL, NULL, NULL, NULL, NULL, NULL,
890 NULL, NULL, NULL, NULL, NULL,
891 NULL, 0, NULL,
892 NULL, NULL, sk_sentbefore, NULL, NULL,
893 0, NULL, NULL, NULL);
894}
895
896struct mailimap_search_key *
897mailimap_search_key_new_senton(struct mailimap_date * sk_senton)
898{
899 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SENTON, NULL, NULL,
900 NULL, NULL, NULL, NULL, NULL, NULL,
901 NULL, NULL, NULL, NULL, NULL,
902 NULL, 0, NULL,
903 NULL, NULL, NULL, sk_senton, NULL,
904 0, NULL, NULL, NULL);
905}
906
907struct mailimap_search_key *
908mailimap_search_key_new_sentsince(struct mailimap_date * sk_sentsince)
909{
910 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SENTSINCE, NULL, NULL,
911 NULL, NULL, NULL, NULL, NULL, NULL,
912 NULL, NULL, NULL, NULL, NULL,
913 NULL, 0, NULL,
914 NULL, NULL, NULL, NULL, sk_sentsince,
915 0, NULL, NULL, NULL);
916}
917
918struct mailimap_search_key *
919mailimap_search_key_new_smaller(uint32_t sk_smaller)
920{
921 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SMALLER, NULL, NULL,
922 NULL, NULL, NULL, NULL, NULL, NULL,
923 NULL, NULL, NULL, NULL, NULL,
924 NULL, 0, NULL,
925 NULL, NULL, NULL, NULL, NULL,
926 sk_smaller, NULL, NULL, NULL);
927}
928
929struct mailimap_search_key *
930mailimap_search_key_new_uid(struct mailimap_set * sk_uid)
931{
932 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_UID, NULL, NULL,
933 NULL, NULL, NULL, NULL, NULL, NULL,
934 NULL, NULL, NULL, NULL, NULL,
935 NULL, 0, NULL,
936 NULL, NULL, NULL, NULL, NULL,
937 0, sk_uid, NULL, NULL);
938}
939
940struct mailimap_search_key *
941mailimap_search_key_new_set(struct mailimap_set * sk_set)
942{
943 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_SET, NULL, NULL,
944 NULL, NULL, NULL, NULL, NULL, NULL,
945 NULL, NULL, NULL, NULL, NULL,
946 NULL, 0, NULL,
947 NULL, NULL, NULL, NULL, NULL,
948 0, NULL, sk_set, NULL);
949}
950
951struct mailimap_search_key *
952mailimap_search_key_new_multiple(clist * sk_multiple)
953{
954 return mailimap_search_key_new(MAILIMAP_SEARCH_KEY_MULTIPLE, NULL, NULL,
955 NULL, NULL, NULL, NULL, NULL, NULL,
956 NULL, NULL, NULL, NULL, NULL,
957 NULL, 0, NULL,
958 NULL, NULL, NULL, NULL, NULL,
959 0, NULL, NULL, sk_multiple);
960}
961
962struct mailimap_search_key *
963mailimap_search_key_new_multiple_empty(void)
964{
965 clist * list;
966
967 list = clist_new();
968 if (list == NULL)
969 return NULL;
970
971 return mailimap_search_key_new_multiple(list);
972}
973
974int
975mailimap_search_key_multiple_add(struct mailimap_search_key * keys,
976 struct mailimap_search_key * key_item)
977{
978 int r;
979
980 r = clist_append(keys->sk_data.sk_multiple, key_item);
981 if (r < 0)
982 return MAILIMAP_ERROR_MEMORY;
983
984 return MAILIMAP_NO_ERROR;
985}
986
987
988
989/* CAPABILITY */
990/* no args */
991
992/* LOGOUT */
993/* no args */
994
995/* NOOP */
996/* no args */
997
998/* APPEND */
999/* gchar flag_list date_time gchar */
1000
1001struct mailimap_flag_list *
1002mailimap_flag_list_new_empty(void)
1003{
1004 clist * list;
1005
1006 list = clist_new();
1007 if (list == NULL)
1008 return NULL;
1009
1010 return mailimap_flag_list_new(list);
1011}
1012
1013int mailimap_flag_list_add(struct mailimap_flag_list * flag_list,
1014 struct mailimap_flag * f)
1015{
1016 int r;
1017
1018 r = clist_append(flag_list->fl_list, f);
1019 if (r < 0)
1020 return MAILIMAP_ERROR_MEMORY;
1021
1022 return MAILIMAP_NO_ERROR;
1023}
1024
1025struct mailimap_flag * mailimap_flag_new_answered(void)
1026{
1027 return mailimap_flag_new(MAILIMAP_FLAG_ANSWERED, NULL, NULL);
1028}
1029
1030struct mailimap_flag * mailimap_flag_new_flagged(void)
1031{
1032 return mailimap_flag_new(MAILIMAP_FLAG_FLAGGED, NULL, NULL);
1033}
1034
1035struct mailimap_flag * mailimap_flag_new_deleted(void)
1036{
1037 return mailimap_flag_new(MAILIMAP_FLAG_DELETED, NULL, NULL);
1038}
1039
1040struct mailimap_flag * mailimap_flag_new_seen(void)
1041{
1042 return mailimap_flag_new(MAILIMAP_FLAG_SEEN, NULL, NULL);
1043}
1044
1045struct mailimap_flag * mailimap_flag_new_draft(void)
1046{
1047 return mailimap_flag_new(MAILIMAP_FLAG_DRAFT, NULL, NULL);
1048}
1049
1050struct mailimap_flag * mailimap_flag_new_flag_keyword(char * flag_keyword)
1051{
1052 return mailimap_flag_new(MAILIMAP_FLAG_KEYWORD, flag_keyword, NULL);
1053}
1054
1055struct mailimap_flag * mailimap_flag_new_flag_extension(char * flag_extension)
1056{
1057 return mailimap_flag_new(MAILIMAP_FLAG_EXTENSION, NULL, flag_extension);
1058}
1059
1060
1061
1062
1063/* CREATE */
1064/* gchar */
1065
1066/* DELETE */
1067/* gchar */
1068
1069/* EXAMINE */
1070/* gchar */
1071
1072/* LIST */
1073/* gchar gchar */
1074
1075/* LSUB */
1076/* gchar gchar */
1077
1078/* RENAME */
1079/* gchar gchar */
1080
1081/* SELECT */
1082/* gchar */
1083
1084/* STATUS */
1085/* gchar GList of status_att */
1086
1087struct mailimap_status_att_list * mailimap_status_att_list_new_empty(void)
1088{
1089 clist * list;
1090
1091 list = clist_new();
1092 if (list == NULL)
1093 return NULL;
1094
1095 return mailimap_status_att_list_new(list);
1096}
1097
1098int
1099mailimap_status_att_list_add(struct mailimap_status_att_list * sa_list,
1100 int status_att)
1101{
1102 int * pstatus_att;
1103 int r;
1104
1105 pstatus_att = malloc(sizeof(* pstatus_att));
1106 * pstatus_att = status_att;
1107
1108 r = clist_append(sa_list->att_list, pstatus_att);
1109 if (r < 0) {
1110 free(pstatus_att);
1111 return MAILIMAP_ERROR_MEMORY;
1112 }
1113
1114 return MAILIMAP_NO_ERROR;
1115}
1116
1117/* SUBSCRIBE */
1118/* gchar */
1119
1120/* UNSUBSCRIBE */
1121/* gchar */
1122
1123/* LOGIN */
1124/* gchar gchar */
1125
1126/* AUTHENTICATE */
1127/* gchar */
1128
1129
1130static int recursive_build_path(struct mailimap_body * root_part,
1131 struct mailimap_body * part,
1132 clist ** result);
1133
1134static int try_build_part(struct mailimap_body * root_part,
1135 struct mailimap_body * part, uint32_t count,
1136 clist ** result)
1137{
1138 int r;
1139 clist * imap_id_list;
1140 uint32_t * id;
1141
1142 r = recursive_build_path(root_part, part, &imap_id_list);
1143 if (r != MAILIMAP_NO_ERROR)
1144 return r;
1145
1146 id = malloc(sizeof(* id));
1147 if (id == NULL) {
1148 clist_free(imap_id_list);
1149 return MAILIMAP_ERROR_MEMORY;
1150 }
1151
1152 * id = count;
1153
1154 r = clist_prepend(imap_id_list, id);
1155 if (r < 0) {
1156 free(id);
1157 clist_free(imap_id_list);
1158 return MAILIMAP_ERROR_MEMORY;
1159 }
1160
1161 * result = imap_id_list;
1162
1163 return MAILIMAP_NO_ERROR;
1164}
1165
1166
1167static int recursive_build_path(struct mailimap_body * root_part,
1168 struct mailimap_body * part,
1169 clist ** result)
1170{
1171 clistiter * cur;
1172 uint32_t count;
1173 int r;
1174 clist * imap_id_list;
1175
1176 if (part == root_part) {
1177 imap_id_list = clist_new();
1178 if (imap_id_list == NULL) {
1179 return MAILIMAP_ERROR_MEMORY;
1180 }
1181
1182 * result = imap_id_list;
1183
1184 return MAILIMAP_NO_ERROR;
1185 }
1186
1187 switch (root_part->bd_type) {
1188 case MAILIMAP_BODY_MPART:
1189 count = 0;
1190 for(cur = clist_begin(root_part->bd_data.bd_body_mpart->bd_list) ;
1191 cur != NULL ; cur = clist_next(cur)) {
1192 struct mailimap_body * current_part;
1193
1194 current_part = clist_content(cur);
1195 count ++;
1196
1197 r = try_build_part(current_part, part, count, &imap_id_list);
1198 if (r == MAILIMAP_ERROR_INVAL) {
1199 continue;
1200 } if (r != MAILIMAP_NO_ERROR) {
1201 return r;
1202 }
1203 else {
1204 * result = imap_id_list;
1205 return MAILIMAP_NO_ERROR;
1206 }
1207 }
1208 return MAILIMAP_ERROR_INVAL;
1209
1210 case MAILIMAP_BODY_1PART:
1211 if (root_part->bd_data.bd_body_1part->bd_type ==
1212 MAILIMAP_BODY_TYPE_1PART_MSG) {
1213 struct mailimap_body * current_part;
1214
1215 current_part =
1216 root_part->bd_data.bd_body_1part->bd_data.bd_type_msg->bd_body;
1217
1218 r = try_build_part(current_part, part, 1, &imap_id_list);
1219 if (r != MAILIMAP_NO_ERROR) {
1220 return r;
1221 }
1222 else {
1223 * result = imap_id_list;
1224 return MAILIMAP_NO_ERROR;
1225 }
1226 }
1227 else {
1228 return MAILIMAP_ERROR_INVAL;
1229 }
1230 break;
1231
1232 default:
1233 return MAILIMAP_ERROR_INVAL;
1234 }
1235}
1236
1237/* return mailimap_section_part from a given mailimap_body */
1238
1239int mailimap_get_section_part_from_body(struct mailimap_body * root_part,
1240 struct mailimap_body * part,
1241 struct mailimap_section_part ** result)
1242{
1243 struct mailimap_section_part * section_part;
1244 clist * id_list;
1245 int r;
1246 int res;
1247
1248 r = recursive_build_path(root_part, part, &id_list);
1249 if (r != MAILIMAP_NO_ERROR) {
1250 res = r;
1251 goto err;
1252 }
1253
1254 section_part = mailimap_section_part_new(id_list);
1255 if (section_part == NULL) {
1256 res = MAILIMAP_ERROR_MEMORY;
1257 goto free_list;
1258 }
1259
1260 * result = section_part;
1261
1262 return MAILIMAP_NO_ERROR;
1263
1264 free_list:
1265 clist_foreach(id_list, (clist_func) free, NULL);
1266 clist_free(id_list);
1267 err:
1268 return res;
1269}
diff --git a/kmicromail/libetpan/imap/mailimap_types_helper.h b/kmicromail/libetpan/imap/mailimap_types_helper.h
new file mode 100644
index 0000000..bb0bb99
--- a/dev/null
+++ b/kmicromail/libetpan/imap/mailimap_types_helper.h
@@ -0,0 +1,758 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_TYPES_HELPER_H
37
38#define MAILIMAP_TYPES_HELPER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailimap_types.h>
45
46/*
47 IMPORTANT NOTE:
48
49 All allocation functions will take as argument allocated data
50 and will store these data in the structure they will allocate.
51 Data should be persistant during all the use of the structure
52 and will be freed by the free function of the structure
53
54 allocation functions will return NULL on failure
55*/
56
57/*
58 this function creates a new set item with a single message
59 given by index
60*/
61
62struct mailimap_set_item * mailimap_set_item_new_single(uint32_t index);
63
64/*
65 this function creates a new set with one set item
66 */
67
68struct mailimap_set *
69mailimap_set_new_single_item(struct mailimap_set_item * item);
70
71/*
72 this function creates a set with a single interval
73*/
74
75struct mailimap_set * mailimap_set_new_interval(uint32_t first, uint32_t last);
76
77/*
78 this function creates a set with a single message
79*/
80
81struct mailimap_set * mailimap_set_new_single(uint32_t index);
82
83/*
84 this function creates an empty set of messages
85*/
86
87struct mailimap_set * mailimap_set_new_empty(void);
88
89/*
90 this function adds a set item to the set of messages
91
92 @return MAILIMAP_NO_ERROR will be returned on success,
93 other code will be returned otherwise
94*/
95
96int mailimap_set_add(struct mailimap_set * set,
97 struct mailimap_set_item * set_item);
98
99/*
100 this function adds an interval to the set
101
102 @return MAILIMAP_NO_ERROR will be returned on success,
103 other code will be returned otherwise
104*/
105
106int mailimap_set_add_interval(struct mailimap_set * set,
107 uint32_t first, uint32_t last);
108
109/*
110 this function adds a single message to the set
111
112 @return MAILIMAP_NO_ERROR will be returned on success,
113 other code will be returned otherwise
114*/
115
116int mailimap_set_add_single(struct mailimap_set * set,
117 uint32_t index);
118
119/*
120 this function creates a mailimap_section structure to request
121 the header of a message
122*/
123
124struct mailimap_section * mailimap_section_new_header(void);
125
126/*
127 this functions creates a mailimap_section structure to describe
128 a list of headers
129*/
130
131struct mailimap_section *
132mailimap_section_new_header_fields(struct mailimap_header_list * header_list);
133
134/*
135 this functions creates a mailimap_section structure to describe headers
136 other than those given
137*/
138
139struct mailimap_section *
140mailimap_section_new_header_fields_not(struct mailimap_header_list * header_list);
141
142/*
143 this function creates a mailimap_section structure to describe the
144 text of a message
145 */
146
147struct mailimap_section * mailimap_section_new_text(void);
148
149/*
150 this function creates a mailimap_section structure to describe the
151 content of a MIME part
152*/
153
154struct mailimap_section *
155mailimap_section_new_part(struct mailimap_section_part * part);
156
157/*
158 this function creates a mailimap_section structure to describe the
159 MIME fields of a MIME part
160*/
161
162struct mailimap_section *
163mailimap_section_new_part_mime(struct mailimap_section_part * part);
164
165/*
166 this function creates a mailimap_section structure to describe the
167 headers of a MIME part if the MIME type is a message/rfc822
168*/
169
170struct mailimap_section *
171mailimap_section_new_part_header(struct mailimap_section_part * part);
172
173/*
174 this function creates a mailimap_section structure to describe
175 a list of headers of a MIME part if the MIME type is a message/rfc822
176*/
177
178struct mailimap_section *
179mailimap_section_new_part_header_fields(struct mailimap_section_part *
180 part,
181 struct mailimap_header_list *
182 header_list);
183
184/*
185 this function creates a mailimap_section structure to describe
186 headers of a MIME part other than those given if the MIME type
187 is a message/rfc822
188*/
189
190struct mailimap_section *
191mailimap_section_new_part_header_fields_not(struct mailimap_section_part
192 * part,
193 struct mailimap_header_list
194 * header_list);
195
196/*
197 this function creates a mailimap_section structure to describe
198 text part of message if the MIME type is a message/rfc822
199*/
200
201struct mailimap_section *
202mailimap_section_new_part_text(struct mailimap_section_part * part);
203
204
205/*
206 this function creates a mailimap_fetch_att structure to request
207 envelope of a message
208*/
209
210struct mailimap_fetch_att *
211mailimap_fetch_att_new_envelope(void);
212
213
214/*
215 this function creates a mailimap_fetch_att structure to request
216 flags of a message
217*/
218
219struct mailimap_fetch_att *
220mailimap_fetch_att_new_flags(void);
221
222/*
223 this function creates a mailimap_fetch_att structure to request
224 internal date of a message
225*/
226
227struct mailimap_fetch_att *
228mailimap_fetch_att_new_internaldate(void);
229
230
231/*
232 this function creates a mailimap_fetch_att structure to request
233 text part of a message
234*/
235
236struct mailimap_fetch_att *
237mailimap_fetch_att_new_rfc822(void);
238
239
240/*
241 this function creates a mailimap_fetch_att structure to request
242 header of a message
243*/
244
245struct mailimap_fetch_att *
246mailimap_fetch_att_new_rfc822_header(void);
247
248/*
249 this function creates a mailimap_fetch_att structure to request
250 size of a message
251*/
252
253struct mailimap_fetch_att *
254mailimap_fetch_att_new_rfc822_size(void);
255
256/*
257 this function creates a mailimap_fetch_att structure to request
258 envelope of a message
259*/
260
261struct mailimap_fetch_att *
262mailimap_fetch_att_new_rfc822_text(void);
263
264/*
265 this function creates a mailimap_fetch_att structure to request
266 the MIME structure of a message
267*/
268
269struct mailimap_fetch_att *
270mailimap_fetch_att_new_body(void);
271
272/*
273 this function creates a mailimap_fetch_att structure to request
274 the MIME structure of a message and additional MIME information
275*/
276
277struct mailimap_fetch_att *
278mailimap_fetch_att_new_bodystructure(void);
279
280/*
281 this function creates a mailimap_fetch_att structure to request
282 unique identifier of a message
283*/
284
285struct mailimap_fetch_att *
286mailimap_fetch_att_new_uid(void);
287
288/*
289 this function creates a mailimap_fetch_att structure to request
290 a given section of a message
291*/
292
293struct mailimap_fetch_att *
294mailimap_fetch_att_new_body_section(struct mailimap_section * section);
295
296/*
297 this function creates a mailimap_fetch_att structure to request
298 a given section of a message without marking it as read
299*/
300
301struct mailimap_fetch_att *
302mailimap_fetch_att_new_body_peek_section(struct mailimap_section * section);
303
304/*
305 this function creates a mailimap_fetch_att structure to request
306 a part of a section of a message
307*/
308
309struct mailimap_fetch_att *
310mailimap_fetch_att_new_body_section_partial(struct mailimap_section * section,
311 uint32_t offset, uint32_t size);
312
313/*
314 this function creates a mailimap_fetch_att structure to request
315 a part of a section of a message without marking it as read
316*/
317
318struct mailimap_fetch_att *
319mailimap_fetch_att_new_body_peek_section_partial(struct mailimap_section * section,
320 uint32_t offset, uint32_t size);
321
322/*
323 this function creates a mailimap_fetch_type structure to request
324 (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE) of a message
325*/
326
327struct mailimap_fetch_type *
328mailimap_fetch_type_new_all(void);
329
330/*
331 this function creates a mailimap_fetch_type structure to request
332 (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY)
333*/
334
335struct mailimap_fetch_type *
336mailimap_fetch_type_new_full(void);
337
338/*
339 this function creates a mailimap_fetch_type structure to request
340 (FLAGS INTERNALDATE RFC822.SIZE)
341*/
342
343struct mailimap_fetch_type *
344mailimap_fetch_type_new_fast(void);
345
346/*
347 this function creates a mailimap_fetch_type structure to request
348 the given fetch attribute
349*/
350
351struct mailimap_fetch_type *
352mailimap_fetch_type_new_fetch_att(struct mailimap_fetch_att * fetch_att);
353
354/*
355 this function creates a mailimap_fetch_type structure to request
356 the list of fetch attributes
357*/
358
359struct mailimap_fetch_type *
360mailimap_fetch_type_new_fetch_att_list(clist * fetch_att_list);
361
362/*
363 this function creates a mailimap_fetch_type structure
364*/
365
366struct mailimap_fetch_type *
367mailimap_fetch_type_new_fetch_att_list_empty(void);
368
369/*
370 this function adds a given fetch attribute to the mailimap_fetch
371 structure
372
373 @return MAILIMAP_NO_ERROR will be returned on success,
374 other code will be returned otherwise
375*/
376
377int
378mailimap_fetch_type_new_fetch_att_list_add(struct mailimap_fetch_type *
379 fetch_type,
380 struct mailimap_fetch_att *
381 fetch_att);
382
383/*
384 this function creates a store attribute to set the given flags
385*/
386
387struct mailimap_store_att_flags *
388mailimap_store_att_flags_new_set_flags(struct mailimap_flag_list * flags);
389
390/*
391 this function creates a store attribute to silently set the given flags
392*/
393
394struct mailimap_store_att_flags *
395mailimap_store_att_flags_new_set_flags_silent(struct mailimap_flag_list *
396 flags);
397
398/*
399 this function creates a store attribute to add the given flags
400*/
401
402struct mailimap_store_att_flags *
403mailimap_store_att_flags_new_add_flags(struct mailimap_flag_list * flags);
404
405/*
406 this function creates a store attribute to add silently the given flags
407*/
408
409struct mailimap_store_att_flags *
410mailimap_store_att_flags_new_add_flags_silent(struct mailimap_flag_list *
411 flags);
412
413/*
414 this function creates a store attribute to remove the given flags
415*/
416
417struct mailimap_store_att_flags *
418mailimap_store_att_flags_new_remove_flags(struct mailimap_flag_list * flags);
419
420/*
421 this function creates a store attribute to remove silently the given flags
422*/
423
424struct mailimap_store_att_flags *
425mailimap_store_att_flags_new_remove_flags_silent(struct mailimap_flag_list *
426 flags);
427
428
429/*
430 this function creates a condition structure to match all messages
431*/
432
433struct mailimap_search_key *
434mailimap_search_key_new_all(void);
435
436/*
437 this function creates a condition structure to match messages with Bcc field
438
439 @param bcc this is the content of Bcc to match, it should be allocated
440 with malloc()
441*/
442
443struct mailimap_search_key *
444mailimap_search_key_new_bcc(char * sk_bcc);
445
446/*
447 this function creates a condition structure to match messages with
448 internal date
449*/
450
451struct mailimap_search_key *
452mailimap_search_key_new_before(struct mailimap_date * sk_before);
453
454/*
455 this function creates a condition structure to match messages with
456 message content
457
458 @param body this is the content of the message to match, it should
459 be allocated with malloc()
460*/
461
462struct mailimap_search_key *
463mailimap_search_key_new_body(char * sk_body);
464
465/*
466 this function creates a condition structure to match messages with
467 Cc field
468
469
470 @param cc this is the content of Cc to match, it should be allocated
471 with malloc()
472*/
473
474struct mailimap_search_key *
475mailimap_search_key_new_cc(char * sk_cc);
476
477/*
478 this function creates a condition structure to match messages with
479 From field
480
481 @param from this is the content of From to match, it should be allocated
482 with malloc()
483*/
484
485struct mailimap_search_key *
486mailimap_search_key_new_from(char * sk_from);
487
488/*
489 this function creates a condition structure to match messages with
490 a flag given by keyword
491*/
492
493struct mailimap_search_key *
494mailimap_search_key_new_keyword(char * sk_keyword);
495
496/*
497 this function creates a condition structure to match messages with
498 internal date
499*/
500
501struct mailimap_search_key *
502mailimap_search_key_new_on(struct mailimap_date * sk_on);
503
504/*
505 this function creates a condition structure to match messages with
506 internal date
507*/
508
509struct mailimap_search_key *
510mailimap_search_key_new_since(struct mailimap_date * sk_since);
511
512/*
513 this function creates a condition structure to match messages with
514 Subject field
515
516 @param subject this is the content of Subject to match, it should
517 be allocated with malloc()
518*/
519
520struct mailimap_search_key *
521mailimap_search_key_new_subject(char * sk_subject);
522
523/*
524 this function creates a condition structure to match messages with
525 message text part
526
527 @param text this is the message text to match, it should
528 be allocated with malloc()
529*/
530
531struct mailimap_search_key *
532mailimap_search_key_new_text(char * sk_text);
533
534/*
535 this function creates a condition structure to match messages with
536 To field
537
538 @param to this is the content of To to match, it should be allocated
539 with malloc()
540*/
541
542struct mailimap_search_key *
543mailimap_search_key_new_to(char * sk_to);
544
545/*
546 this function creates a condition structure to match messages with
547 no a flag given by unkeyword
548*/
549
550struct mailimap_search_key *
551mailimap_search_key_new_unkeyword(char * sk_unkeyword);
552
553/*
554 this function creates a condition structure to match messages with
555 the given field
556
557 @param header_name this is the name of the field to match, it
558 should be allocated with malloc()
559
560 @param header_value this is the content, it should be allocated
561 with malloc()
562*/
563
564struct mailimap_search_key *
565mailimap_search_key_new_header(char * sk_header_name, char * sk_header_value);
566
567
568/*
569 this function creates a condition structure to match messages with size
570*/
571
572struct mailimap_search_key *
573mailimap_search_key_new_larger(uint32_t sk_larger);
574
575/*
576 this function creates a condition structure to match messages that
577 do not match the given condition
578*/
579
580struct mailimap_search_key *
581mailimap_search_key_new_not(struct mailimap_search_key * sk_not);
582
583/*
584 this function creates a condition structure to match messages that
585 match one of the given conditions
586*/
587
588struct mailimap_search_key *
589mailimap_search_key_new_or(struct mailimap_search_key * sk_or1,
590 struct mailimap_search_key * sk_or2);
591
592/*
593 this function creates a condition structure to match messages
594 with Date field
595*/
596
597struct mailimap_search_key *
598mailimap_search_key_new_sentbefore(struct mailimap_date * sk_sentbefore);
599
600/*
601 this function creates a condition structure to match messages
602 with Date field
603*/
604
605struct mailimap_search_key *
606mailimap_search_key_new_senton(struct mailimap_date * sk_senton);
607
608/*
609 this function creates a condition structure to match messages
610 with Date field
611*/
612
613struct mailimap_search_key *
614mailimap_search_key_new_sentsince(struct mailimap_date * sk_sentsince);
615
616/*
617 this function creates a condition structure to match messages with size
618*/
619
620struct mailimap_search_key *
621mailimap_search_key_new_smaller(uint32_t sk_smaller);
622
623/*
624 this function creates a condition structure to match messages with unique
625 identifier
626*/
627
628struct mailimap_search_key *
629mailimap_search_key_new_uid(struct mailimap_set * sk_uid);
630
631/*
632 this function creates a condition structure to match messages with number
633 or unique identifier (depending whether SEARCH or UID SEARCH is used)
634*/
635
636struct mailimap_search_key *
637mailimap_search_key_new_set(struct mailimap_set * sk_set);
638
639/*
640 this function creates a condition structure to match messages that match
641 all the conditions given in the list
642*/
643
644struct mailimap_search_key *
645mailimap_search_key_new_multiple(clist * sk_multiple);
646
647
648/*
649 same as previous but the list is empty
650*/
651
652struct mailimap_search_key *
653mailimap_search_key_new_multiple_empty(void);
654
655/*
656 this function adds a condition to the condition list
657
658 @return MAILIMAP_NO_ERROR will be returned on success,
659 other code will be returned otherwise
660*/
661
662int
663mailimap_search_key_multiple_add(struct mailimap_search_key * keys,
664 struct mailimap_search_key * key_item);
665
666
667/*
668 this function creates an empty list of flags
669*/
670
671struct mailimap_flag_list *
672mailimap_flag_list_new_empty(void);
673
674/*
675 this function adds a flag to the list of flags
676
677 @return MAILIMAP_NO_ERROR will be returned on success,
678 other code will be returned otherwise
679*/
680
681int mailimap_flag_list_add(struct mailimap_flag_list * flag_list,
682 struct mailimap_flag * f);
683
684/*
685 this function creates a \Answered flag
686*/
687
688struct mailimap_flag * mailimap_flag_new_answered(void);
689
690/*
691 this function creates a \Flagged flag
692*/
693
694struct mailimap_flag * mailimap_flag_new_flagged(void);
695
696/*
697 this function creates a \Deleted flag
698*/
699
700struct mailimap_flag * mailimap_flag_new_deleted(void);
701
702/*
703 this function creates a \Seen flag
704*/
705
706struct mailimap_flag * mailimap_flag_new_seen(void);
707
708/*
709 this function creates a \Draft flag
710*/
711
712struct mailimap_flag * mailimap_flag_new_draft(void);
713
714/*
715 this function creates a keyword flag
716
717 @param flag_keyword this should be allocated with malloc()
718*/
719
720struct mailimap_flag * mailimap_flag_new_flag_keyword(char * flag_keyword);
721
722
723/*
724 this function creates an extension flag
725
726 @param flag_extension this should be allocated with malloc()
727*/
728
729struct mailimap_flag * mailimap_flag_new_flag_extension(char * flag_extension);
730
731/*
732 this function creates an empty list of status attributes
733*/
734
735struct mailimap_status_att_list * mailimap_status_att_list_new_empty(void);
736
737/*
738 this function adds status attributes to the list
739
740 @return MAILIMAP_NO_ERROR will be returned on success,
741 other code will be returned otherwise
742*/
743
744int
745mailimap_status_att_list_add(struct mailimap_status_att_list * sa_list,
746 int status_att);
747
748/* return mailimap_section_part from a given mailimap_body */
749
750int mailimap_get_section_part_from_body(struct mailimap_body * root_part,
751 struct mailimap_body * part,
752 struct mailimap_section_part ** result);
753
754#ifdef __cplusplus
755}
756#endif
757
758#endif
diff --git a/kmicromail/libetpan/imf/.libs/libmailimf.a b/kmicromail/libetpan/imf/.libs/libmailimf.a
new file mode 100644
index 0000000..833c4f3
--- a/dev/null
+++ b/kmicromail/libetpan/imf/.libs/libmailimf.a
Binary files differ
diff --git a/kmicromail/libetpan/imf/TODO b/kmicromail/libetpan/imf/TODO
new file mode 100644
index 0000000..8fcd271
--- a/dev/null
+++ b/kmicromail/libetpan/imf/TODO
@@ -0,0 +1,16 @@
1- define a EP_parserstate_s
2- structure to union
3- remove clist usage
4- add a errorcode to string function
5- error codes are EP_errornr_s
6- prefix everything with EP_
7- replace mailimf_write to fnprintf-like
8 fnprintf = fnprintf( int (*)(void *Data, char *
9 Buf, long l ), void * Data, char * Format, ... )
10- mailimf_dot_atom_text_free
11- mailimf_address_XX -> _new(void) _init(&addr, ...) _free(addr)
12- in fact that data structure should then also contain a
13 'dynamically' allocated flag
14
15- RFC 822 : test the examples
16- RFC 2822 : obsolete syntax
diff --git a/kmicromail/libetpan/imf/mailimf.c b/kmicromail/libetpan/imf/mailimf.c
new file mode 100644
index 0000000..84d81a1
--- a/dev/null
+++ b/kmicromail/libetpan/imf/mailimf.c
@@ -0,0 +1,7585 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimf.h"
37
38/*
39 RFC 2822
40
41 RFC 2821 ...
42 A message-originating SMTP system SHOULD NOT send a message that
43 already contains a Return-path header. SMTP servers performing a
44 relay function MUST NOT inspect the message data, and especially not
45 to the extent needed to determine if Return-path headers are present.
46 SMTP servers making final delivery MAY remove Return-path headers
47 before adding their own.
48*/
49
50#include <ctype.h>
51#include <mmapstring.h>
52#include <stdlib.h>
53#include <string.h>
54
55#ifndef TRUE
56#define TRUE 1
57#endif
58
59#ifndef FALSE
60#define FALSE 0
61#endif
62
63
64
65
66
67
68
69static inline int is_dtext(char ch);
70
71static int mailimf_quoted_pair_parse(const char * message, size_t length,
72 size_t * index, char * result);
73
74static int mailimf_ccontent_parse(const char * message, size_t length,
75 size_t * index);
76
77static int
78mailimf_comment_fws_ccontent_parse(const char * message, size_t length,
79 size_t * index);
80
81static inline int mailimf_comment_parse(const char * message, size_t length,
82 size_t * index);
83
84static int mailimf_qcontent_parse(const char * message, size_t length,
85 size_t * index, char * ch);
86
87static int mailimf_phrase_parse(const char * message, size_t length,
88 size_t * index, char ** result);
89
90static int mailimf_unstructured_parse(const char * message, size_t length,
91 size_t * index, char ** result);
92
93static int mailimf_ignore_unstructured_parse(const char * message, size_t length,
94 size_t * index);
95
96static int mailimf_day_of_week_parse(const char * message, size_t length,
97 size_t * index, int * result);
98
99static int mailimf_day_name_parse(const char * message, size_t length,
100 size_t * index, int * result);
101
102static int mailimf_date_parse(const char * message, size_t length,
103 size_t * index,
104 int * pday, int * pmonth, int * pyear);
105
106static int mailimf_year_parse(const char * message, size_t length,
107 size_t * index, int * result);
108
109static int mailimf_month_parse(const char * message, size_t length,
110 size_t * index, int * result);
111
112static int mailimf_month_name_parse(const char * message, size_t length,
113 size_t * index, int * result);
114
115static int mailimf_day_parse(const char * message, size_t length,
116 size_t * index, int * result);
117
118static int mailimf_time_parse(const char * message, size_t length,
119 size_t * index,
120 int * phour, int * pmin,
121 int * psec,
122 int * zone);
123static int mailimf_time_of_day_parse(const char * message, size_t length,
124 size_t * index,
125 int * phour, int * pmin,
126 int * psec);
127
128static int mailimf_hour_parse(const char * message, size_t length,
129 size_t * index, int * result);
130
131static int mailimf_minute_parse(const char * message, size_t length,
132 size_t * index, int * result);
133
134static int mailimf_second_parse(const char * message, size_t length,
135 size_t * index, int * result);
136
137static int mailimf_zone_parse(const char * message, size_t length,
138 size_t * index, int * result);
139
140static int mailimf_name_addr_parse(const char * message, size_t length,
141 size_t * index,
142 char ** pdisplay_name,
143 char ** pangle_addr);
144
145static int mailimf_angle_addr_parse(const char * message, size_t length,
146 size_t * index, char ** result);
147
148static int mailimf_group_parse(const char * message, size_t length,
149 size_t * index,
150 struct mailimf_group ** result);
151
152static int mailimf_display_name_parse(const char * message, size_t length,
153 size_t * index, char ** result);
154
155static int mailimf_addr_spec_parse(const char * message, size_t length,
156 size_t * index,
157 char ** address);
158
159#if 0
160static int mailimf_local_part_parse(const char * message, size_t length,
161 size_t * index,
162 char ** result);
163
164static int mailimf_domain_parse(const char * message, size_t length,
165 size_t * index,
166 char ** result);
167#endif
168
169#if 0
170static int mailimf_domain_literal_parse(const char * message, size_t length,
171 size_t * index, char ** result);
172#endif
173
174#if 0
175static int mailimf_dcontent_parse(const char * message, size_t length,
176 size_t * index, char * result);
177#endif
178
179static int
180mailimf_orig_date_parse(const char * message, size_t length,
181 size_t * index, struct mailimf_orig_date ** result);
182
183static int
184mailimf_from_parse(const char * message, size_t length,
185 size_t * index, struct mailimf_from ** result);
186
187static int
188mailimf_sender_parse(const char * message, size_t length,
189 size_t * index, struct mailimf_sender ** result);
190
191static int
192mailimf_reply_to_parse(const char * message, size_t length,
193 size_t * index, struct mailimf_reply_to ** result);
194
195static int
196mailimf_to_parse(const char * message, size_t length,
197 size_t * index, struct mailimf_to ** result);
198
199static int
200mailimf_cc_parse(const char * message, size_t length,
201 size_t * index, struct mailimf_cc ** result);
202
203static int
204mailimf_bcc_parse(const char * message, size_t length,
205 size_t * index, struct mailimf_bcc ** result);
206
207static int mailimf_message_id_parse(const char * message, size_t length,
208 size_t * index,
209 struct mailimf_message_id ** result);
210
211static int
212mailimf_in_reply_to_parse(const char * message, size_t length,
213 size_t * index,
214 struct mailimf_in_reply_to ** result);
215
216#if 0
217static int mailimf_references_parse(const char * message, size_t length,
218 size_t * index,
219 struct mailimf_references **
220 result);
221#endif
222
223static int mailimf_unstrict_msg_id_parse(const char * message, size_t length,
224 size_t * index,
225 char ** result);
226
227#if 0
228static int mailimf_id_left_parse(const char * message, size_t length,
229 size_t * index, char ** result);
230
231static int mailimf_id_right_parse(const char * message, size_t length,
232 size_t * index, char ** result);
233#endif
234
235#if 0
236static int mailimf_no_fold_quote_parse(const char * message, size_t length,
237 size_t * index, char ** result);
238
239static int mailimf_no_fold_literal_parse(const char * message, size_t length,
240 size_t * index, char ** result);
241#endif
242
243static int mailimf_subject_parse(const char * message, size_t length,
244 size_t * index,
245 struct mailimf_subject ** result);
246
247static int mailimf_comments_parse(const char * message, size_t length,
248 size_t * index,
249 struct mailimf_comments ** result);
250
251static int mailimf_keywords_parse(const char * message, size_t length,
252 size_t * index,
253 struct mailimf_keywords ** result);
254
255static int
256mailimf_resent_date_parse(const char * message, size_t length,
257 size_t * index, struct mailimf_orig_date ** result);
258
259static int
260mailimf_resent_from_parse(const char * message, size_t length,
261 size_t * index, struct mailimf_from ** result);
262
263static int
264mailimf_resent_sender_parse(const char * message, size_t length,
265 size_t * index, struct mailimf_sender ** result);
266
267static int
268mailimf_resent_to_parse(const char * message, size_t length,
269 size_t * index, struct mailimf_to ** result);
270
271static int
272mailimf_resent_cc_parse(const char * message, size_t length,
273 size_t * index, struct mailimf_cc ** result);
274
275static int
276mailimf_resent_bcc_parse(const char * message, size_t length,
277 size_t * index, struct mailimf_bcc ** result);
278
279static int
280mailimf_resent_msg_id_parse(const char * message, size_t length,
281 size_t * index,
282 struct mailimf_message_id ** result);
283
284static int mailimf_return_parse(const char * message, size_t length,
285 size_t * index,
286 struct mailimf_return ** result);
287
288static int
289mailimf_path_parse(const char * message, size_t length,
290 size_t * index, struct mailimf_path ** result);
291
292static int
293mailimf_optional_field_parse(const char * message, size_t length,
294 size_t * index,
295 struct mailimf_optional_field ** result);
296
297static int mailimf_field_name_parse(const char * message, size_t length,
298 size_t * index, char ** result);
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324/* *************************************************************** */
325
326static inline int is_digit(char ch)
327{
328 return (ch >= '0') && (ch <= '9');
329}
330
331static int mailimf_digit_parse(const char * message, size_t length,
332 size_t * index, int * result)
333{
334 size_t cur_token;
335
336 cur_token = * index;
337
338 if (cur_token >= length)
339 return MAILIMF_ERROR_PARSE;
340
341 if (is_digit(message[cur_token])) {
342 * result = message[cur_token] - '0';
343 cur_token ++;
344 * index = cur_token;
345 return MAILIMF_NO_ERROR;
346 }
347 else
348 return MAILIMF_ERROR_PARSE;
349}
350
351int
352mailimf_number_parse(const char * message, size_t length,
353 size_t * index, uint32_t * result)
354{
355 size_t cur_token;
356 int digit;
357 uint32_t number;
358 int parsed;
359 int r;
360
361 cur_token = * index;
362 parsed = FALSE;
363
364 number = 0;
365 while (1) {
366 r = mailimf_digit_parse(message, length, &cur_token, &digit);
367 if (r != MAILIMF_NO_ERROR) {
368 if (r == MAILIMF_ERROR_PARSE)
369 break;
370 else
371 return r;
372 }
373 number *= 10;
374 number += digit;
375 parsed = TRUE;
376 }
377
378 if (!parsed)
379 return MAILIMF_ERROR_PARSE;
380
381 * result = number;
382 * index = cur_token;
383
384 return MAILIMF_NO_ERROR;
385}
386
387int mailimf_char_parse(const char * message, size_t length,
388 size_t * index, char token)
389{
390 size_t cur_token;
391
392 cur_token = * index;
393
394 if (cur_token >= length)
395 return MAILIMF_ERROR_PARSE;
396
397 if (message[cur_token] == token) {
398 cur_token ++;
399 * index = cur_token;
400 return MAILIMF_NO_ERROR;
401 }
402 else
403 return MAILIMF_ERROR_PARSE;
404}
405
406int mailimf_unstrict_char_parse(const char * message, size_t length,
407 size_t * index, char token)
408{
409 size_t cur_token;
410 int r;
411
412 cur_token = * index;
413
414 r = mailimf_cfws_parse(message, length, &cur_token);
415 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
416 return r;
417
418 r = mailimf_char_parse(message, length, &cur_token, token);
419 if (r != MAILIMF_NO_ERROR)
420 return r;
421
422 * index = cur_token;
423
424 return MAILIMF_NO_ERROR;
425}
426
427int
428mailimf_token_case_insensitive_len_parse(const char * message, size_t length,
429 size_t * index, char * token,
430 size_t token_length)
431{
432 size_t cur_token;
433
434 cur_token = * index;
435
436 if (cur_token + token_length - 1 >= length)
437 return MAILIMF_ERROR_PARSE;
438
439 if (strncasecmp(message + cur_token, token, token_length) == 0) {
440 cur_token += token_length;
441 * index = cur_token;
442 return MAILIMF_NO_ERROR;
443 }
444 else
445 return MAILIMF_ERROR_PARSE;
446}
447
448static int mailimf_oparenth_parse(const char * message, size_t length,
449 size_t * index)
450{
451 return mailimf_char_parse(message, length, index, '(');
452}
453
454static int mailimf_cparenth_parse(const char * message, size_t length,
455 size_t * index)
456{
457 return mailimf_char_parse(message, length, index, ')');
458}
459
460static int mailimf_comma_parse(const char * message, size_t length,
461 size_t * index)
462{
463 return mailimf_unstrict_char_parse(message, length, index, ',');
464}
465
466static int mailimf_dquote_parse(const char * message, size_t length,
467 size_t * index)
468{
469 return mailimf_char_parse(message, length, index, '\"');
470}
471
472static int mailimf_colon_parse(const char * message, size_t length,
473 size_t * index)
474{
475 return mailimf_unstrict_char_parse(message, length, index, ':');
476}
477
478static int mailimf_semi_colon_parse(const char * message, size_t length,
479 size_t * index)
480{
481 return mailimf_unstrict_char_parse(message, length, index, ';');
482}
483
484static int mailimf_plus_parse(const char * message, size_t length,
485 size_t * index)
486{
487 return mailimf_unstrict_char_parse(message, length, index, '+');
488}
489
490static int mailimf_minus_parse(const char * message, size_t length,
491 size_t * index)
492{
493 return mailimf_unstrict_char_parse(message, length, index, '-');
494}
495
496static int mailimf_lower_parse(const char * message, size_t length,
497 size_t * index)
498{
499 return mailimf_unstrict_char_parse(message, length, index, '<');
500}
501
502static int mailimf_greater_parse(const char * message, size_t length,
503 size_t * index)
504{
505 return mailimf_unstrict_char_parse(message, length, index, '>');
506}
507
508#if 0
509static int mailimf_obracket_parse(const char * message, size_t length,
510 size_t * index)
511{
512 return mailimf_unstrict_char_parse(message, length, index, '[');
513}
514
515static int mailimf_cbracket_parse(const char * message, size_t length,
516 size_t * index)
517{
518 return mailimf_unstrict_char_parse(message, length, index, ']');
519}
520#endif
521
522static int mailimf_at_sign_parse(const char * message, size_t length,
523 size_t * index)
524{
525 return mailimf_unstrict_char_parse(message, length, index, '@');
526}
527
528static int mailimf_point_parse(const char * message, size_t length,
529 size_t * index)
530{
531 return mailimf_unstrict_char_parse(message, length, index, '.');
532}
533
534int
535mailimf_custom_string_parse(const char * message, size_t length,
536 size_t * index, char ** result,
537 int (* is_custom_char)(char))
538{
539 size_t begin;
540 size_t end;
541 char * gstr;
542
543 begin = * index;
544
545 end = begin;
546
547 if (end >= length)
548 return MAILIMF_ERROR_PARSE;
549
550 while (is_custom_char(message[end])) {
551 end ++;
552 if (end >= length)
553 break;
554 }
555
556 if (end != begin) {
557 /*
558 gstr = strndup(message + begin, end - begin);
559 */
560 gstr = malloc(end - begin + 1);
561 if (gstr == NULL)
562 return MAILIMF_ERROR_MEMORY;
563 strncpy(gstr, message + begin, end - begin);
564 gstr[end - begin] = '\0';
565
566 * index = end;
567 * result = gstr;
568 return MAILIMF_NO_ERROR;
569 }
570 else
571 return MAILIMF_ERROR_PARSE;
572}
573
574
575
576
577
578
579
580typedef int mailimf_struct_parser(const char * message, size_t length,
581 size_t * index, void * result);
582
583typedef int mailimf_struct_destructor(void * result);
584
585
586static int
587mailimf_struct_multiple_parse(const char * message, size_t length,
588 size_t * index, clist ** result,
589 mailimf_struct_parser * parser,
590 mailimf_struct_destructor * destructor)
591{
592 clist * struct_list;
593 size_t cur_token;
594 void * value;
595 int r;
596 int res;
597
598 cur_token = * index;
599
600 r = parser(message, length, &cur_token, &value);
601 if (r != MAILIMF_NO_ERROR) {
602 res = r;
603 goto err;
604 }
605
606 struct_list = clist_new();
607 if (struct_list == NULL) {
608 destructor(value);
609 res = MAILIMF_ERROR_MEMORY;
610 goto err;
611 }
612
613 r = clist_append(struct_list, value);
614 if (r < 0) {
615 destructor(value);
616 res = MAILIMF_ERROR_MEMORY;
617 goto free;
618 }
619
620 while (1) {
621 r = parser(message, length, &cur_token, &value);
622 if (r != MAILIMF_NO_ERROR) {
623 if (r == MAILIMF_ERROR_PARSE)
624 break;
625 else {
626 res = r;
627 goto free;
628 }
629 }
630 r = clist_append(struct_list, value);
631 if (r < 0) {
632 (* destructor)(value);
633 res = MAILIMF_ERROR_MEMORY;
634 goto free;
635 }
636 }
637
638 * result = struct_list;
639 * index = cur_token;
640
641 return MAILIMF_NO_ERROR;
642
643 free:
644 clist_foreach(struct_list, (clist_func) destructor, NULL);
645 clist_free(struct_list);
646 err:
647 return res;
648}
649
650
651
652static int
653mailimf_struct_list_parse(const char * message, size_t length,
654 size_t * index, clist ** result,
655 char symbol,
656 mailimf_struct_parser * parser,
657 mailimf_struct_destructor * destructor)
658{
659 clist * struct_list;
660 size_t cur_token;
661 void * value;
662 size_t final_token;
663 int r;
664 int res;
665
666 cur_token = * index;
667
668 r = parser(message, length, &cur_token, &value);
669 if (r != MAILIMF_NO_ERROR) {
670 res = r;
671 goto err;
672 }
673
674 struct_list = clist_new();
675 if (struct_list == NULL) {
676 destructor(value);
677 res = MAILIMF_ERROR_MEMORY;
678 goto err;
679 }
680
681 r = clist_append(struct_list, value);
682 if (r < 0) {
683 destructor(value);
684 res = MAILIMF_ERROR_MEMORY;
685 goto free;
686 }
687
688 final_token = cur_token;
689
690 while (1) {
691 r = mailimf_unstrict_char_parse(message, length, &cur_token, symbol);
692 if (r != MAILIMF_NO_ERROR) {
693 if (r == MAILIMF_ERROR_PARSE)
694 break;
695 else {
696 res = r;
697 goto free;
698 }
699 }
700
701 r = parser(message, length, &cur_token, &value);
702 if (r != MAILIMF_NO_ERROR) {
703 if (r == MAILIMF_ERROR_PARSE)
704 break;
705 else {
706 res = r;
707 goto free;
708 }
709 }
710
711 r = clist_append(struct_list, value);
712 if (r < 0) {
713 destructor(value);
714 res = MAILIMF_ERROR_MEMORY;
715 goto free;
716 }
717
718 final_token = cur_token;
719 }
720
721 * result = struct_list;
722 * index = final_token;
723
724 return MAILIMF_NO_ERROR;
725
726 free:
727 clist_foreach(struct_list, (clist_func) destructor, NULL);
728 clist_free(struct_list);
729 err:
730 return res;
731}
732
733static inline int mailimf_wsp_parse(const char * message, size_t length,
734 size_t * index)
735{
736 size_t cur_token;
737
738 cur_token = * index;
739
740 if (cur_token >= length)
741 return MAILIMF_ERROR_PARSE;
742
743 if ((message[cur_token] != ' ') && (message[cur_token] != '\t'))
744 return MAILIMF_ERROR_PARSE;
745
746 cur_token ++;
747 * index = cur_token;
748
749 return MAILIMF_NO_ERROR;
750}
751
752
753int mailimf_crlf_parse(const char * message, size_t length, size_t * index)
754{
755 size_t cur_token;
756 int r;
757
758 cur_token = * index;
759
760 r = mailimf_char_parse(message, length, &cur_token, '\r');
761 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
762 return r;
763
764 r = mailimf_char_parse(message, length, &cur_token, '\n');
765 if (r != MAILIMF_NO_ERROR)
766 return r;
767
768 * index = cur_token;
769 return MAILIMF_NO_ERROR;
770}
771
772static int mailimf_unstrict_crlf_parse(const char * message,
773 size_t length, size_t * index)
774{
775 size_t cur_token;
776 int r;
777
778 cur_token = * index;
779
780 mailimf_cfws_parse(message, length, &cur_token);
781
782 r = mailimf_char_parse(message, length, &cur_token, '\r');
783 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
784 return r;
785
786 r = mailimf_char_parse(message, length, &cur_token, '\n');
787 if (r != MAILIMF_NO_ERROR)
788 return r;
789
790 * index = cur_token;
791 return MAILIMF_NO_ERROR;
792}
793
794/* ************************************************************************ */
795
796
797
798/* RFC 2822 grammar */
799
800/*
801NO-WS-CTL = %d1-8 / ; US-ASCII control characters
802 %d11 / ; that do not include the
803 %d12 / ; carriage return, line feed,
804 %d14-31 / ; and white space characters
805 %d127
806*/
807
808static inline int is_no_ws_ctl(char ch)
809{
810 if ((ch == 9) || (ch == 10) || (ch == 13))
811 return FALSE;
812
813 if (ch == 127)
814 return TRUE;
815
816 return (ch >= 1) && (ch <= 31);
817}
818
819/*
820text = %d1-9 / ; Characters excluding CR and LF
821 %d11 /
822 %d12 /
823 %d14-127 /
824 obs-text
825*/
826
827/*
828specials = "(" / ")" / ; Special characters used in
829 "<" / ">" / ; other parts of the syntax
830 "[" / "]" /
831 ":" / ";" /
832 "@" / "\" /
833 "," / "." /
834 DQUOTE
835*/
836
837/*
838quoted-pair = ("\" text) / obs-qp
839*/
840
841static inline int mailimf_quoted_pair_parse(const char * message, size_t length,
842 size_t * index, char * result)
843{
844 size_t cur_token;
845
846 cur_token = * index;
847
848 if (cur_token + 1 >= length)
849 return MAILIMF_ERROR_PARSE;
850
851 if (message[cur_token] != '\\')
852 return MAILIMF_ERROR_PARSE;
853
854 cur_token ++;
855 * result = message[cur_token];
856 cur_token ++;
857 * index = cur_token;
858
859 return MAILIMF_NO_ERROR;
860}
861
862/*
863FWS = ([*WSP CRLF] 1*WSP) / ; Folding white space
864 obs-FWS
865*/
866
867int mailimf_fws_parse(const char * message, size_t length, size_t * index)
868{
869 size_t cur_token;
870 size_t final_token;
871 int fws_1;
872 int fws_2;
873 int fws_3;
874 int r;
875
876 cur_token = * index;
877
878 fws_1 = FALSE;
879 while (1) {
880 r = mailimf_wsp_parse(message, length, &cur_token);
881 if (r != MAILIMF_NO_ERROR) {
882 if (r == MAILIMF_ERROR_PARSE)
883 break;
884 else
885 return r;
886 }
887 fws_1 = TRUE;
888 }
889 final_token = cur_token;
890
891 r = mailimf_crlf_parse(message, length, &cur_token);
892 switch (r) {
893 case MAILIMF_NO_ERROR:
894 fws_2 = TRUE;
895 break;
896 case MAILIMF_ERROR_PARSE:
897 fws_2 = FALSE;
898 break;
899 default:
900 return r;
901 }
902
903 fws_3 = FALSE;
904 if (fws_2) {
905 while (1) {
906 r = mailimf_wsp_parse(message, length, &cur_token);
907 if (r != MAILIMF_NO_ERROR) {
908 if (r == MAILIMF_ERROR_PARSE)
909 break;
910 else
911 return r;
912 }
913 fws_3 = TRUE;
914 }
915 }
916
917 if ((!fws_1) && (!fws_3))
918 return MAILIMF_ERROR_PARSE;
919
920 if (!fws_3)
921 cur_token = final_token;
922
923 * index = cur_token;
924
925 return MAILIMF_NO_ERROR;
926}
927
928
929/*
930ctext = NO-WS-CTL / ; Non white space controls
931
932 %d33-39 / ; The rest of the US-ASCII
933 %d42-91 / ; characters not including "(",
934 %d93-126 ; ")", or "\"
935*/
936
937static inline int is_ctext(char ch)
938{
939 unsigned char uch = (unsigned char) ch;
940
941 if (is_no_ws_ctl(ch))
942 return TRUE;
943
944 if (uch < 33)
945 return FALSE;
946
947 if ((uch == 40) || (uch == 41))
948 return FALSE;
949
950 if (uch == 92)
951 return FALSE;
952
953 if (uch == 127)
954 return FALSE;
955
956 return TRUE;
957}
958
959/*
960ccontent = ctext / quoted-pair / comment
961*/
962
963static inline int mailimf_ccontent_parse(const char * message, size_t length,
964 size_t * index)
965{
966 size_t cur_token;
967 char ch;
968 int r;
969
970 cur_token = * index;
971
972 if (cur_token >= length)
973 return MAILIMF_ERROR_PARSE;
974
975 if (is_ctext(message[cur_token])) {
976 cur_token ++;
977 }
978 else {
979 r = mailimf_quoted_pair_parse(message, length, &cur_token, &ch);
980
981 if (r == MAILIMF_ERROR_PARSE)
982 r = mailimf_comment_parse(message, length, &cur_token);
983
984 if (r == MAILIMF_ERROR_PARSE)
985 return r;
986 }
987
988 * index = cur_token;
989
990 return MAILIMF_NO_ERROR;
991}
992
993/*
994[FWS] ccontent
995*/
996
997static inline int
998mailimf_comment_fws_ccontent_parse(const char * message, size_t length,
999 size_t * index)
1000{
1001 size_t cur_token;
1002 int r;
1003
1004 cur_token = * index;
1005
1006 r = mailimf_fws_parse(message, length, &cur_token);
1007 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
1008 return r;
1009
1010 r = mailimf_ccontent_parse(message, length, &cur_token);
1011 if (r != MAILIMF_NO_ERROR)
1012 return r;
1013
1014 * index = cur_token;
1015
1016 return MAILIMF_NO_ERROR;
1017}
1018
1019/*
1020comment = "(" *([FWS] ccontent) [FWS] ")"
1021*/
1022
1023static inline int mailimf_comment_parse(const char * message, size_t length,
1024 size_t * index)
1025{
1026 size_t cur_token;
1027 int r;
1028
1029 cur_token = * index;
1030
1031 r = mailimf_oparenth_parse(message, length, &cur_token);
1032 if (r != MAILIMF_NO_ERROR)
1033 return r;
1034
1035 while (1) {
1036 r = mailimf_comment_fws_ccontent_parse(message, length, &cur_token);
1037 if (r != MAILIMF_NO_ERROR) {
1038 if (r == MAILIMF_ERROR_PARSE)
1039 break;
1040 else
1041 return r;
1042 }
1043 }
1044
1045 r = mailimf_fws_parse(message, length, &cur_token);
1046 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
1047 return r;
1048
1049 r = mailimf_cparenth_parse(message, length, &cur_token);
1050 if (r != MAILIMF_NO_ERROR)
1051 return r;
1052
1053 * index = cur_token;
1054
1055 return MAILIMF_NO_ERROR;
1056}
1057
1058/*
1059[FWS] comment
1060*/
1061
1062static inline int mailimf_cfws_fws_comment_parse(const char * message, size_t length,
1063 size_t * index)
1064{
1065 size_t cur_token;
1066 int r;
1067
1068 cur_token = * index;
1069
1070 r = mailimf_fws_parse(message, length, &cur_token);
1071 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
1072 return r;
1073
1074 r = mailimf_comment_parse(message, length, &cur_token);
1075 if (r != MAILIMF_NO_ERROR)
1076 return r;
1077
1078 * index = cur_token;
1079
1080 return MAILIMF_NO_ERROR;
1081}
1082
1083/*
1084CFWS = *([FWS] comment) (([FWS] comment) / FWS)
1085*/
1086
1087int mailimf_cfws_parse(const char * message, size_t length,
1088 size_t * index)
1089{
1090 size_t cur_token;
1091 int has_comment;
1092 int r;
1093
1094 cur_token = * index;
1095
1096 has_comment = FALSE;
1097 while (1) {
1098 r = mailimf_cfws_fws_comment_parse(message, length, &cur_token);
1099 if (r != MAILIMF_NO_ERROR) {
1100 if (r == MAILIMF_ERROR_PARSE)
1101 break;
1102 else
1103 return r;
1104 }
1105 has_comment = TRUE;
1106 }
1107
1108 if (!has_comment) {
1109 r = mailimf_fws_parse(message, length, &cur_token);
1110 if (r != MAILIMF_NO_ERROR)
1111 return r;
1112 }
1113
1114 * index = cur_token;
1115
1116 return MAILIMF_NO_ERROR;
1117}
1118
1119/*
1120atext = ALPHA / DIGIT / ; Any character except controls,
1121 "!" / "#" / ; SP, and specials.
1122 "$" / "%" / ; Used for atoms
1123 "&" / "'" /
1124 "*" / "+" /
1125 "-" / "/" /
1126 "=" / "?" /
1127 "^" / "_" /
1128 "`" / "{" /
1129 "|" / "}" /
1130 "~"
1131*/
1132
1133static inline int is_atext(char ch)
1134{
1135 switch (ch) {
1136 case ' ':
1137 case '\t':
1138 case '\n':
1139 case '\r':
1140#if 0
1141 case '(':
1142 case ')':
1143#endif
1144 case '<':
1145 case '>':
1146#if 0
1147 case '@':
1148#endif
1149 case ',':
1150 case '"':
1151 case ':':
1152 case ';':
1153 return FALSE;
1154 default:
1155 return TRUE;
1156 }
1157}
1158
1159/*
1160atom = [CFWS] 1*atext [CFWS]
1161*/
1162
1163int mailimf_atom_parse(const char * message, size_t length,
1164 size_t * index, char ** result)
1165{
1166 size_t cur_token;
1167 int r;
1168 int res;
1169 char * atom;
1170 size_t end;
1171
1172 cur_token = * index;
1173
1174 r = mailimf_cfws_parse(message, length, &cur_token);
1175 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
1176 res = r;
1177 goto err;
1178 }
1179
1180 end = cur_token;
1181 if (end >= length) {
1182 res = MAILIMF_ERROR_PARSE;
1183 goto err;
1184 }
1185
1186 while (is_atext(message[end])) {
1187 end ++;
1188 if (end >= length)
1189 break;
1190 }
1191 if (end == cur_token) {
1192 res = MAILIMF_ERROR_PARSE;
1193 goto err;
1194 }
1195
1196 atom = malloc(end - cur_token + 1);
1197 if (atom == NULL) {
1198 res = MAILIMF_ERROR_MEMORY;
1199 goto err;
1200 }
1201 strncpy(atom, message + cur_token, end - cur_token);
1202 atom[end - cur_token] = '\0';
1203
1204 cur_token = end;
1205
1206 * index = cur_token;
1207 * result = atom;
1208
1209 return MAILIMF_NO_ERROR;
1210
1211 err:
1212 return res;
1213}
1214
1215int mailimf_fws_atom_parse(const char * message, size_t length,
1216 size_t * index, char ** result)
1217{
1218 size_t cur_token;
1219 int r;
1220 int res;
1221 char * atom;
1222 size_t end;
1223
1224 cur_token = * index;
1225
1226 r = mailimf_fws_parse(message, length, &cur_token);
1227 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
1228 res = r;
1229 goto err;
1230 }
1231
1232 end = cur_token;
1233 if (end >= length) {
1234 res = MAILIMF_ERROR_PARSE;
1235 goto err;
1236 }
1237
1238 while (is_atext(message[end])) {
1239 end ++;
1240 if (end >= length)
1241 break;
1242 }
1243 if (end == cur_token) {
1244 res = MAILIMF_ERROR_PARSE;
1245 goto err;
1246 }
1247
1248 atom = malloc(end - cur_token + 1);
1249 if (atom == NULL) {
1250 res = MAILIMF_ERROR_MEMORY;
1251 goto err;
1252 }
1253 strncpy(atom, message + cur_token, end - cur_token);
1254 atom[end - cur_token] = '\0';
1255
1256 cur_token = end;
1257
1258 * index = cur_token;
1259 * result = atom;
1260
1261 return MAILIMF_NO_ERROR;
1262
1263 err:
1264 return res;
1265}
1266
1267/*
1268dot-atom = [CFWS] dot-atom-text [CFWS]
1269*/
1270
1271#if 0
1272static int mailimf_dot_atom_parse(const char * message, size_t length,
1273 size_t * index, char ** result)
1274{
1275 return mailimf_atom_parse(message, length, index, result);
1276}
1277#endif
1278
1279/*
1280dot-atom-text = 1*atext *("." 1*atext)
1281*/
1282
1283#if 0
1284static int
1285mailimf_dot_atom_text_parse(const char * message, size_t length,
1286 size_t * index, char ** result)
1287{
1288 return mailimf_atom_parse(message, length, index, result);
1289}
1290#endif
1291
1292/*
1293qtext = NO-WS-CTL / ; Non white space controls
1294
1295 %d33 / ; The rest of the US-ASCII
1296 %d35-91 / ; characters not including "\"
1297 %d93-126 ; or the quote character
1298*/
1299
1300static inline int is_qtext(char ch)
1301{
1302 unsigned char uch = (unsigned char) ch;
1303
1304 if (is_no_ws_ctl(ch))
1305 return TRUE;
1306
1307 if (uch < 33)
1308 return FALSE;
1309
1310 if (uch == 34)
1311 return FALSE;
1312
1313 if (uch == 92)
1314 return FALSE;
1315
1316 if (uch == 127)
1317 return FALSE;
1318
1319 return TRUE;
1320}
1321
1322/*
1323qcontent = qtext / quoted-pair
1324*/
1325
1326static int mailimf_qcontent_parse(const char * message, size_t length,
1327 size_t * index, char * result)
1328{
1329 size_t cur_token;
1330 char ch;
1331 int r;
1332
1333 cur_token = * index;
1334
1335 if (cur_token >= length)
1336 return MAILIMF_ERROR_PARSE;
1337
1338 if (is_qtext(message[cur_token])) {
1339 ch = message[cur_token];
1340 cur_token ++;
1341 }
1342 else {
1343 r = mailimf_quoted_pair_parse(message, length, &cur_token, &ch);
1344
1345 if (r != MAILIMF_NO_ERROR)
1346 return r;
1347 }
1348
1349 * result = ch;
1350 * index = cur_token;
1351
1352 return MAILIMF_NO_ERROR;
1353}
1354
1355/*
1356quoted-string = [CFWS]
1357 DQUOTE *([FWS] qcontent) [FWS] DQUOTE
1358 [CFWS]
1359*/
1360
1361int mailimf_quoted_string_parse(const char * message, size_t length,
1362 size_t * index, char ** result)
1363{
1364 size_t cur_token;
1365 MMAPString * gstr;
1366 char ch;
1367 char * str;
1368 int r;
1369 int res;
1370
1371 cur_token = * index;
1372
1373 r = mailimf_cfws_parse(message, length, &cur_token);
1374 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
1375 res = r;
1376 goto err;
1377 }
1378
1379 r = mailimf_dquote_parse(message, length, &cur_token);
1380 if (r != MAILIMF_NO_ERROR) {
1381 res = r;
1382 goto err;
1383 }
1384
1385 gstr = mmap_string_new("");
1386 if (gstr == NULL) {
1387 res = MAILIMF_ERROR_MEMORY;
1388 goto err;
1389 }
1390
1391#if 0
1392 if (mmap_string_append_c(gstr, '\"') == NULL) {
1393 res = MAILIMF_ERROR_MEMORY;
1394 goto free_gstr;
1395 }
1396#endif
1397
1398 while (1) {
1399 r = mailimf_fws_parse(message, length, &cur_token);
1400 if (r == MAILIMF_NO_ERROR) {
1401 if (mmap_string_append_c(gstr, ' ') == NULL) {
1402 res = MAILIMF_ERROR_MEMORY;
1403 goto free_gstr;
1404 }
1405 }
1406 else if (r != MAILIMF_ERROR_PARSE) {
1407 res = r;
1408 goto free_gstr;
1409 }
1410
1411 r = mailimf_qcontent_parse(message, length, &cur_token, &ch);
1412 if (r == MAILIMF_NO_ERROR) {
1413 if (mmap_string_append_c(gstr, ch) == NULL) {
1414 res = MAILIMF_ERROR_MEMORY;
1415 goto free_gstr;
1416 }
1417 }
1418 else if (r == MAILIMF_ERROR_PARSE)
1419 break;
1420 else {
1421 res = r;
1422 goto free_gstr;
1423 }
1424 }
1425
1426 r = mailimf_dquote_parse(message, length, &cur_token);
1427 if (r != MAILIMF_NO_ERROR) {
1428 res = r;
1429 goto free_gstr;
1430 }
1431
1432#if 0
1433 if (mmap_string_append_c(gstr, '\"') == NULL) {
1434 res = MAILIMF_ERROR_MEMORY;
1435 goto free_gstr;
1436 }
1437#endif
1438
1439 str = strdup(gstr->str);
1440 if (str == NULL) {
1441 res = MAILIMF_ERROR_MEMORY;
1442 goto free_gstr;
1443 }
1444 mmap_string_free(gstr);
1445
1446 * index = cur_token;
1447 * result = str;
1448
1449 return MAILIMF_NO_ERROR;
1450
1451 free_gstr:
1452 mmap_string_free(gstr);
1453 err:
1454 return res;
1455}
1456
1457int mailimf_fws_quoted_string_parse(const char * message, size_t length,
1458 size_t * index, char ** result)
1459{
1460 size_t cur_token;
1461 MMAPString * gstr;
1462 char ch;
1463 char * str;
1464 int r;
1465 int res;
1466
1467 cur_token = * index;
1468
1469 r = mailimf_fws_parse(message, length, &cur_token);
1470 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
1471 res = r;
1472 goto err;
1473 }
1474
1475 r = mailimf_dquote_parse(message, length, &cur_token);
1476 if (r != MAILIMF_NO_ERROR) {
1477 res = r;
1478 goto err;
1479 }
1480
1481 gstr = mmap_string_new("");
1482 if (gstr == NULL) {
1483 res = MAILIMF_ERROR_MEMORY;
1484 goto err;
1485 }
1486
1487#if 0
1488 if (mmap_string_append_c(gstr, '\"') == NULL) {
1489 res = MAILIMF_ERROR_MEMORY;
1490 goto free_gstr;
1491 }
1492#endif
1493
1494 while (1) {
1495 r = mailimf_fws_parse(message, length, &cur_token);
1496 if (r == MAILIMF_NO_ERROR) {
1497 if (mmap_string_append_c(gstr, ' ') == NULL) {
1498 res = MAILIMF_ERROR_MEMORY;
1499 goto free_gstr;
1500 }
1501 }
1502 else if (r != MAILIMF_ERROR_PARSE) {
1503 res = r;
1504 goto free_gstr;
1505 }
1506
1507 r = mailimf_qcontent_parse(message, length, &cur_token, &ch);
1508 if (r == MAILIMF_NO_ERROR) {
1509 if (mmap_string_append_c(gstr, ch) == NULL) {
1510 res = MAILIMF_ERROR_MEMORY;
1511 goto free_gstr;
1512 }
1513 }
1514 else if (r == MAILIMF_ERROR_PARSE)
1515 break;
1516 else {
1517 res = r;
1518 goto free_gstr;
1519 }
1520 }
1521
1522 r = mailimf_dquote_parse(message, length, &cur_token);
1523 if (r != MAILIMF_NO_ERROR) {
1524 res = r;
1525 goto free_gstr;
1526 }
1527
1528#if 0
1529 if (mmap_string_append_c(gstr, '\"') == NULL) {
1530 res = MAILIMF_ERROR_MEMORY;
1531 goto free_gstr;
1532 }
1533#endif
1534
1535 str = strdup(gstr->str);
1536 if (str == NULL) {
1537 res = MAILIMF_ERROR_MEMORY;
1538 goto free_gstr;
1539 }
1540 mmap_string_free(gstr);
1541
1542 * index = cur_token;
1543 * result = str;
1544
1545 return MAILIMF_NO_ERROR;
1546
1547 free_gstr:
1548 mmap_string_free(gstr);
1549 err:
1550 return res;
1551}
1552
1553/*
1554word = atom / quoted-string
1555*/
1556
1557int mailimf_word_parse(const char * message, size_t length,
1558 size_t * index, char ** result)
1559{
1560 size_t cur_token;
1561 char * word;
1562 int r;
1563
1564 cur_token = * index;
1565
1566 r = mailimf_atom_parse(message, length, &cur_token, &word);
1567
1568 if (r == MAILIMF_ERROR_PARSE)
1569 r = mailimf_quoted_string_parse(message, length, &cur_token, &word);
1570
1571 if (r != MAILIMF_NO_ERROR)
1572 return r;
1573
1574 * result = word;
1575 * index = cur_token;
1576
1577 return MAILIMF_NO_ERROR;
1578}
1579
1580int mailimf_fws_word_parse(const char * message, size_t length,
1581 size_t * index, char ** result)
1582{
1583 size_t cur_token;
1584 char * word;
1585 int r;
1586
1587 cur_token = * index;
1588
1589 r = mailimf_fws_atom_parse(message, length, &cur_token, &word);
1590
1591 if (r == MAILIMF_ERROR_PARSE)
1592 r = mailimf_fws_quoted_string_parse(message, length, &cur_token, &word);
1593
1594 if (r != MAILIMF_NO_ERROR)
1595 return r;
1596
1597 * result = word;
1598 * index = cur_token;
1599
1600 return MAILIMF_NO_ERROR;
1601}
1602
1603/*
1604phrase = 1*word / obs-phrase
1605*/
1606
1607static int mailimf_phrase_parse(const char * message, size_t length,
1608 size_t * index, char ** result)
1609{
1610 MMAPString * gphrase;
1611 char * word;
1612 int first;
1613 size_t cur_token;
1614 int r;
1615 int res;
1616 char * str;
1617
1618 cur_token = * index;
1619
1620 gphrase = mmap_string_new("");
1621 if (gphrase == NULL) {
1622 res = MAILIMF_ERROR_MEMORY;
1623 goto err;
1624 }
1625
1626 first = TRUE;
1627
1628 while (1) {
1629 r = mailimf_fws_word_parse(message, length, &cur_token, &word);
1630 if (r == MAILIMF_NO_ERROR) {
1631 if (!first) {
1632 if (mmap_string_append_c(gphrase, ' ') == NULL) {
1633 mailimf_word_free(word);
1634 res = MAILIMF_ERROR_MEMORY;
1635 goto free;
1636 }
1637 }
1638 if (mmap_string_append(gphrase, word) == NULL) {
1639 mailimf_word_free(word);
1640 res = MAILIMF_ERROR_MEMORY;
1641 goto free;
1642 }
1643 mailimf_word_free(word);
1644 first = FALSE;
1645 }
1646 else if (r == MAILIMF_ERROR_PARSE)
1647 break;
1648 else {
1649 res = r;
1650 goto free;
1651 }
1652 }
1653
1654 if (first) {
1655 res = MAILIMF_ERROR_PARSE;
1656 goto free;
1657 }
1658
1659 str = strdup(gphrase->str);
1660 if (str == NULL) {
1661 res = MAILIMF_ERROR_MEMORY;
1662 goto free;
1663 }
1664 mmap_string_free(gphrase);
1665
1666 * result = str;
1667 * index = cur_token;
1668
1669 return MAILIMF_NO_ERROR;
1670
1671 free:
1672 mmap_string_free(gphrase);
1673 err:
1674 return res;
1675}
1676
1677/*
1678utext = NO-WS-CTL / ; Non white space controls
1679 %d33-126 / ; The rest of US-ASCII
1680 obs-utext
1681
1682added : WSP
1683*/
1684
1685enum {
1686 UNSTRUCTURED_START,
1687 UNSTRUCTURED_CR,
1688 UNSTRUCTURED_LF,
1689 UNSTRUCTURED_WSP,
1690 UNSTRUCTURED_OUT
1691};
1692
1693static int mailimf_unstructured_parse(const char * message, size_t length,
1694 size_t * index, char ** result)
1695{
1696 size_t cur_token;
1697 int state;
1698 size_t begin;
1699 size_t terminal;
1700 char * str;
1701
1702 cur_token = * index;
1703
1704
1705 while (1) {
1706 int r;
1707
1708 r = mailimf_wsp_parse(message, length, &cur_token);
1709 if (r == MAILIMF_NO_ERROR) {
1710 /* do nothing */
1711 }
1712 else if (r == MAILIMF_ERROR_PARSE)
1713 break;
1714 else {
1715 return r;
1716 }
1717 }
1718
1719 state = UNSTRUCTURED_START;
1720 begin = cur_token;
1721 terminal = cur_token;
1722
1723 while (state != UNSTRUCTURED_OUT) {
1724
1725 switch(state) {
1726 case UNSTRUCTURED_START:
1727 if (cur_token >= length)
1728 return MAILIMF_ERROR_PARSE;
1729
1730 terminal = cur_token;
1731 switch(message[cur_token]) {
1732 case '\r':
1733 state = UNSTRUCTURED_CR;
1734 break;
1735 case '\n':
1736 state = UNSTRUCTURED_LF;
1737 break;
1738 default:
1739 state = UNSTRUCTURED_START;
1740 break;
1741 }
1742 break;
1743 case UNSTRUCTURED_CR:
1744 if (cur_token >= length)
1745 return MAILIMF_ERROR_PARSE;
1746
1747 switch(message[cur_token]) {
1748 case '\n':
1749 state = UNSTRUCTURED_LF;
1750 break;
1751 default:
1752 state = UNSTRUCTURED_START;
1753 break;
1754 }
1755 break;
1756
1757 case UNSTRUCTURED_LF:
1758 if (cur_token >= length) {
1759 state = UNSTRUCTURED_OUT;
1760 break;
1761 }
1762
1763 switch(message[cur_token]) {
1764 case '\t':
1765 case ' ':
1766 state = UNSTRUCTURED_WSP;
1767 break;
1768 default:
1769 state = UNSTRUCTURED_OUT;
1770 break;
1771 }
1772 break;
1773 case UNSTRUCTURED_WSP:
1774 if (cur_token >= length)
1775 return MAILIMF_ERROR_PARSE;
1776
1777 switch(message[cur_token]) {
1778 case '\r':
1779 state = UNSTRUCTURED_CR;
1780 break;
1781 case '\n':
1782 state = UNSTRUCTURED_LF;
1783 break;
1784 default:
1785 state = UNSTRUCTURED_START;
1786 break;
1787 }
1788 break;
1789 }
1790
1791 cur_token ++;
1792 }
1793
1794 str = malloc(terminal - begin + 1);
1795 if (str == NULL)
1796 return MAILIMF_ERROR_MEMORY;
1797 strncpy(str, message + begin, terminal - begin);
1798 str[terminal - begin] = '\0';
1799
1800 * index = terminal;
1801 * result = str;
1802
1803 return MAILIMF_NO_ERROR;
1804}
1805
1806
1807static int mailimf_ignore_unstructured_parse(const char * message, size_t length,
1808 size_t * index)
1809{
1810 size_t cur_token;
1811 int state;
1812 size_t terminal;
1813
1814 cur_token = * index;
1815
1816 state = UNSTRUCTURED_START;
1817 terminal = cur_token;
1818
1819 while (state != UNSTRUCTURED_OUT) {
1820
1821 switch(state) {
1822 case UNSTRUCTURED_START:
1823 if (cur_token >= length)
1824 return MAILIMF_ERROR_PARSE;
1825 terminal = cur_token;
1826 switch(message[cur_token]) {
1827 case '\r':
1828 state = UNSTRUCTURED_CR;
1829 break;
1830 case '\n':
1831 state = UNSTRUCTURED_LF;
1832 break;
1833 default:
1834 state = UNSTRUCTURED_START;
1835 break;
1836 }
1837 break;
1838 case UNSTRUCTURED_CR:
1839 if (cur_token >= length)
1840 return MAILIMF_ERROR_PARSE;
1841 switch(message[cur_token]) {
1842 case '\n':
1843 state = UNSTRUCTURED_LF;
1844 break;
1845 default:
1846 state = UNSTRUCTURED_START;
1847 break;
1848 }
1849 break;
1850 case UNSTRUCTURED_LF:
1851 if (cur_token >= length) {
1852 state = UNSTRUCTURED_OUT;
1853 break;
1854 }
1855 switch(message[cur_token]) {
1856 case '\t':
1857 case ' ':
1858 state = UNSTRUCTURED_WSP;
1859 break;
1860 default:
1861 state = UNSTRUCTURED_OUT;
1862 break;
1863 }
1864 break;
1865 case UNSTRUCTURED_WSP:
1866 if (cur_token >= length)
1867 return MAILIMF_ERROR_PARSE;
1868 switch(message[cur_token]) {
1869 case '\r':
1870 state = UNSTRUCTURED_CR;
1871 break;
1872 case '\n':
1873 state = UNSTRUCTURED_LF;
1874 break;
1875 default:
1876 state = UNSTRUCTURED_START;
1877 break;
1878 }
1879 break;
1880 }
1881
1882 cur_token ++;
1883 }
1884
1885 * index = terminal;
1886
1887 return MAILIMF_NO_ERROR;
1888}
1889
1890
1891int mailimf_ignore_field_parse(const char * message, size_t length,
1892 size_t * index)
1893{
1894 int has_field;
1895 size_t cur_token;
1896 int state;
1897 size_t terminal;
1898
1899 has_field = FALSE;
1900 cur_token = * index;
1901
1902 terminal = cur_token;
1903 state = UNSTRUCTURED_START;
1904
1905 /* check if this is not a beginning CRLF */
1906
1907 if (cur_token >= length)
1908 return MAILIMF_ERROR_PARSE;
1909
1910 switch (message[cur_token]) {
1911 case '\r':
1912 return MAILIMF_ERROR_PARSE;
1913 case '\n':
1914 return MAILIMF_ERROR_PARSE;
1915 }
1916
1917 while (state != UNSTRUCTURED_OUT) {
1918
1919 switch(state) {
1920 case UNSTRUCTURED_START:
1921 if (cur_token >= length)
1922 return MAILIMF_ERROR_PARSE;
1923
1924 switch(message[cur_token]) {
1925 case '\r':
1926 state = UNSTRUCTURED_CR;
1927 break;
1928 case '\n':
1929 state = UNSTRUCTURED_LF;
1930 break;
1931 case ':':
1932 has_field = TRUE;
1933 state = UNSTRUCTURED_START;
1934 break;
1935 default:
1936 state = UNSTRUCTURED_START;
1937 break;
1938 }
1939 break;
1940 case UNSTRUCTURED_CR:
1941 if (cur_token >= length)
1942 return MAILIMF_ERROR_PARSE;
1943
1944 switch(message[cur_token]) {
1945 case '\n':
1946 state = UNSTRUCTURED_LF;
1947 break;
1948 case ':':
1949 has_field = TRUE;
1950 state = UNSTRUCTURED_START;
1951 break;
1952 default:
1953 state = UNSTRUCTURED_START;
1954 break;
1955 }
1956 break;
1957 case UNSTRUCTURED_LF:
1958 if (cur_token >= length) {
1959 terminal = cur_token;
1960 state = UNSTRUCTURED_OUT;
1961 break;
1962 }
1963
1964 switch(message[cur_token]) {
1965 case '\t':
1966 case ' ':
1967 state = UNSTRUCTURED_WSP;
1968 break;
1969 default:
1970 terminal = cur_token;
1971 state = UNSTRUCTURED_OUT;
1972 break;
1973 }
1974 break;
1975 case UNSTRUCTURED_WSP:
1976 if (cur_token >= length)
1977 return MAILIMF_ERROR_PARSE;
1978
1979 switch(message[cur_token]) {
1980 case '\r':
1981 state = UNSTRUCTURED_CR;
1982 break;
1983 case '\n':
1984 state = UNSTRUCTURED_LF;
1985 break;
1986 case ':':
1987 has_field = TRUE;
1988 state = UNSTRUCTURED_START;
1989 break;
1990 default:
1991 state = UNSTRUCTURED_START;
1992 break;
1993 }
1994 break;
1995 }
1996
1997 cur_token ++;
1998 }
1999
2000 if (!has_field)
2001 return MAILIMF_ERROR_PARSE;
2002
2003 * index = terminal;
2004
2005 return MAILIMF_NO_ERROR;
2006}
2007
2008
2009/*
2010date-time = [ day-of-week "," ] date FWS time [CFWS]
2011*/
2012
2013int mailimf_date_time_parse(const char * message, size_t length,
2014 size_t * index,
2015 struct mailimf_date_time ** result)
2016{
2017 size_t cur_token;
2018 int day_of_week;
2019 struct mailimf_date_time * date_time;
2020 int day;
2021 int month;
2022 int year;
2023 int hour;
2024 int min;
2025 int sec;
2026 int zone;
2027 int r;
2028
2029 cur_token = * index;
2030
2031 day_of_week = -1;
2032 r = mailimf_day_of_week_parse(message, length, &cur_token, &day_of_week);
2033 if (r == MAILIMF_NO_ERROR) {
2034 r = mailimf_comma_parse(message, length, &cur_token);
2035 if (r != MAILIMF_NO_ERROR)
2036 return r;
2037 }
2038 else if (r != MAILIMF_ERROR_PARSE)
2039 return r;
2040
2041 r = mailimf_date_parse(message, length, &cur_token, &day, &month, &year);
2042 if (r != MAILIMF_NO_ERROR)
2043 return r;
2044
2045 r = mailimf_fws_parse(message, length, &cur_token);
2046 if (r != MAILIMF_NO_ERROR)
2047 return r;
2048
2049 r = mailimf_time_parse(message, length, &cur_token,
2050 &hour, &min, &sec, &zone);
2051 if (r != MAILIMF_NO_ERROR)
2052 return r;
2053
2054 date_time = mailimf_date_time_new(day, month, year, hour, min, sec, zone);
2055 if (date_time == NULL)
2056 return MAILIMF_ERROR_MEMORY;
2057
2058 * index = cur_token;
2059 * result = date_time;
2060
2061 return MAILIMF_NO_ERROR;
2062}
2063
2064/*
2065day-of-week = ([FWS] day-name) / obs-day-of-week
2066*/
2067
2068static int mailimf_day_of_week_parse(const char * message, size_t length,
2069 size_t * index, int * result)
2070{
2071 size_t cur_token;
2072 int day_of_week;
2073 int r;
2074
2075 cur_token = * index;
2076
2077 r = mailimf_cfws_parse(message, length, &cur_token);
2078 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
2079 return r;
2080
2081 r = mailimf_day_name_parse(message, length, &cur_token, &day_of_week);
2082 if (r != MAILIMF_NO_ERROR)
2083 return r;
2084
2085 * index = cur_token;
2086 * result = day_of_week;
2087
2088 return MAILIMF_NO_ERROR;
2089}
2090
2091/*
2092day-name = "Mon" / "Tue" / "Wed" / "Thu" /
2093 "Fri" / "Sat" / "Sun"
2094*/
2095
2096struct mailimf_token_value {
2097 int value;
2098 char * str;
2099};
2100
2101static struct mailimf_token_value day_names[] = {
2102 {1, "Mon"},
2103 {2, "Tue"},
2104 {3, "Wed"},
2105 {4, "Thu"},
2106 {5, "Fri"},
2107 {6, "Sat"},
2108 {7, "Sun"},
2109};
2110
2111enum {
2112 DAY_NAME_START,
2113 DAY_NAME_T,
2114 DAY_NAME_S
2115};
2116
2117static int guess_day_name(const char * message, size_t length, size_t index)
2118{
2119 int state;
2120
2121 state = DAY_NAME_START;
2122
2123 while (1) {
2124
2125 if (index >= length)
2126 return -1;
2127
2128 switch(state) {
2129 case DAY_NAME_START:
2130 switch((char) toupper((unsigned char) message[index])) {
2131 case 'M': /* Mon */
2132 return 1;
2133 break;
2134 case 'T': /* Tue Thu */
2135 state = DAY_NAME_T;
2136 break;
2137 case 'W': /* Wed */
2138 return 3;
2139 case 'F':
2140 return 5;
2141 case 'S': /* Sat Sun */
2142 state = DAY_NAME_S;
2143 break;
2144 default:
2145 return -1;
2146 }
2147 break;
2148 case DAY_NAME_T:
2149 switch((char) toupper((unsigned char) message[index])) {
2150 case 'U':
2151 return 2;
2152 case 'H':
2153 return 4;
2154 default:
2155 return -1;
2156 }
2157 break;
2158 case DAY_NAME_S:
2159 switch((char) toupper((unsigned char) message[index])) {
2160 case 'A':
2161 return 6;
2162 case 'U':
2163 return 7;
2164 default:
2165 return -1;
2166 }
2167 break;
2168 }
2169
2170 index ++;
2171 }
2172}
2173
2174static int mailimf_day_name_parse(const char * message, size_t length,
2175 size_t * index, int * result)
2176{
2177 size_t cur_token;
2178 int day_of_week;
2179 int guessed_day;
2180 int r;
2181
2182 cur_token = * index;
2183
2184 guessed_day = guess_day_name(message, length, cur_token);
2185 if (guessed_day == -1)
2186 return MAILIMF_ERROR_PARSE;
2187
2188 r = mailimf_token_case_insensitive_parse(message, length,
2189 &cur_token,
2190 day_names[guessed_day - 1].str);
2191 if (r != MAILIMF_NO_ERROR)
2192 return r;
2193
2194 day_of_week = guessed_day;
2195
2196 * result = day_of_week;
2197 * index = cur_token;
2198
2199 return MAILIMF_NO_ERROR;
2200}
2201
2202/*
2203date = day month year
2204*/
2205
2206static int mailimf_date_parse(const char * message, size_t length,
2207 size_t * index,
2208 int * pday, int * pmonth, int * pyear)
2209{
2210 size_t cur_token;
2211 int day;
2212 int month;
2213 int year;
2214 int r;
2215
2216 cur_token = * index;
2217
2218 r = mailimf_day_parse(message, length, &cur_token, &day);
2219 if (r != MAILIMF_NO_ERROR)
2220 return r;
2221
2222 r = mailimf_month_parse(message, length, &cur_token, &month);
2223 if (r != MAILIMF_NO_ERROR)
2224 return r;
2225
2226 r = mailimf_year_parse(message, length, &cur_token, &year);
2227 if (r != MAILIMF_NO_ERROR)
2228 return r;
2229
2230 * pday = day;
2231 * pmonth = month;
2232 * pyear = year;
2233
2234 * index = cur_token;
2235
2236 return MAILIMF_NO_ERROR;
2237}
2238
2239/*
2240year = 4*DIGIT / obs-year
2241*/
2242
2243static int mailimf_year_parse(const char * message, size_t length,
2244 size_t * index, int * result)
2245{
2246 uint32_t number;
2247 size_t cur_token;
2248 int r;
2249
2250 cur_token = * index;
2251
2252 r = mailimf_cfws_parse(message, length, &cur_token);
2253 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
2254 return r;
2255
2256 r = mailimf_number_parse(message, length, &cur_token, &number);
2257 if (r != MAILIMF_NO_ERROR)
2258 return r;
2259
2260 * index = cur_token;
2261 * result = number;
2262
2263 return MAILIMF_NO_ERROR;
2264}
2265
2266/*
2267month = (FWS month-name FWS) / obs-month
2268*/
2269
2270static int mailimf_month_parse(const char * message, size_t length,
2271 size_t * index, int * result)
2272{
2273 size_t cur_token;
2274 int month;
2275 int r;
2276
2277 cur_token = * index;
2278
2279 r = mailimf_cfws_parse(message, length, &cur_token);
2280 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
2281 return r;
2282
2283 r = mailimf_month_name_parse(message, length, &cur_token, &month);
2284 if (r != MAILIMF_NO_ERROR)
2285 return r;
2286
2287 * result = month;
2288 * index = cur_token;
2289
2290 return MAILIMF_NO_ERROR;
2291}
2292
2293/*
2294month-name = "Jan" / "Feb" / "Mar" / "Apr" /
2295 "May" / "Jun" / "Jul" / "Aug" /
2296 "Sep" / "Oct" / "Nov" / "Dec"
2297*/
2298
2299static struct mailimf_token_value month_names[] = {
2300 {1, "Jan"},
2301 {2, "Feb"},
2302 {3, "Mar"},
2303 {4, "Apr"},
2304 {5, "May"},
2305 {6, "Jun"},
2306 {7, "Jul"},
2307 {8, "Aug"},
2308 {9, "Sep"},
2309 {10, "Oct"},
2310 {11, "Nov"},
2311 {12, "Dec"},
2312};
2313
2314enum {
2315 MONTH_START,
2316 MONTH_J,
2317 MONTH_JU,
2318 MONTH_M,
2319 MONTH_MA,
2320 MONTH_A
2321};
2322
2323static int guess_month(const char * message, size_t length, size_t index)
2324{
2325 int state;
2326
2327 state = MONTH_START;
2328
2329 while (1) {
2330
2331 if (index >= length)
2332 return -1;
2333
2334 switch(state) {
2335 case MONTH_START:
2336 switch((char) toupper((unsigned char) message[index])) {
2337 case 'J': /* Jan Jun Jul */
2338 state = MONTH_J;
2339 break;
2340 case 'F': /* Feb */
2341 return 2;
2342 case 'M': /* Mar May */
2343 state = MONTH_M;
2344 break;
2345 case 'A': /* Apr Aug */
2346 state = MONTH_A;
2347 break;
2348 case 'S': /* Sep */
2349 return 9;
2350 case 'O': /* Oct */
2351 return 10;
2352 case 'N': /* Nov */
2353 return 11;
2354 case 'D': /* Dec */
2355 return 12;
2356 default:
2357 return -1;
2358 }
2359 break;
2360 case MONTH_J:
2361 switch((char) toupper((unsigned char) message[index])) {
2362 case 'A':
2363 return 1;
2364 case 'U':
2365 state = MONTH_JU;
2366 break;
2367 default:
2368 return -1;
2369 }
2370 break;
2371 case MONTH_JU:
2372 switch((char) toupper((unsigned char) message[index])) {
2373 case 'N':
2374 return 6;
2375 case 'L':
2376 return 7;
2377 default:
2378 return -1;
2379 }
2380 break;
2381 case MONTH_M:
2382 switch((char) toupper((unsigned char) message[index])) {
2383 case 'A':
2384 state = MONTH_MA;
2385 break;
2386 default:
2387 return -1;
2388 }
2389 break;
2390 case MONTH_MA:
2391 switch((char) toupper((unsigned char) message[index])) {
2392 case 'Y':
2393 return 5;
2394 case 'R':
2395 return 3;
2396 default:
2397 return -1;
2398 }
2399 break;
2400 case MONTH_A:
2401 switch((char) toupper((unsigned char) message[index])) {
2402 case 'P':
2403 return 4;
2404 case 'U':
2405 return 8;
2406 default:
2407 return -1;
2408 }
2409 break;
2410 }
2411
2412 index ++;
2413 }
2414}
2415
2416static int mailimf_month_name_parse(const char * message, size_t length,
2417 size_t * index, int * result)
2418{
2419 size_t cur_token;
2420 int month;
2421 int guessed_month;
2422 int r;
2423
2424 cur_token = * index;
2425
2426 guessed_month = guess_month(message, length, cur_token);
2427 if (guessed_month == -1)
2428 return MAILIMF_ERROR_PARSE;
2429
2430 r = mailimf_token_case_insensitive_parse(message, length,
2431 &cur_token,
2432 month_names[guessed_month - 1].str);
2433 if (r != MAILIMF_NO_ERROR)
2434 return r;
2435
2436 month = guessed_month;
2437
2438 * result = month;
2439 * index = cur_token;
2440
2441 return MAILIMF_NO_ERROR;
2442}
2443
2444/*
2445day = ([FWS] 1*2DIGIT) / obs-day
2446*/
2447
2448static int mailimf_day_parse(const char * message, size_t length,
2449 size_t * index, int * result)
2450{
2451 size_t cur_token;
2452 uint32_t day;
2453 int r;
2454
2455 cur_token = * index;
2456
2457 r = mailimf_cfws_parse(message, length, &cur_token);
2458 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
2459 return r;
2460
2461 r = mailimf_number_parse(message, length, &cur_token, &day);
2462 if (r != MAILIMF_NO_ERROR)
2463 return r;
2464
2465 * result = day;
2466 * index = cur_token;
2467
2468 return MAILIMF_NO_ERROR;
2469}
2470
2471/*
2472time = time-of-day FWS zone
2473*/
2474
2475static int mailimf_time_parse(const char * message, size_t length,
2476 size_t * index,
2477 int * phour, int * pmin,
2478 int * psec,
2479 int * pzone)
2480{
2481 size_t cur_token;
2482 int hour;
2483 int min;
2484 int sec;
2485 int zone;
2486 int r;
2487
2488 cur_token = * index;
2489
2490 r = mailimf_cfws_parse(message, length, &cur_token);
2491 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
2492 return r;
2493
2494 r = mailimf_time_of_day_parse(message, length, &cur_token,
2495 &hour, &min, &sec);
2496 if (r != MAILIMF_NO_ERROR)
2497 return r;
2498
2499 r = mailimf_fws_parse(message, length, &cur_token);
2500 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
2501 return r;
2502
2503 r = mailimf_zone_parse(message, length, &cur_token, &zone);
2504 if (r == MAILIMF_NO_ERROR) {
2505 /* do nothing */
2506 }
2507 else if (r == MAILIMF_ERROR_PARSE) {
2508 zone = 0;
2509 }
2510 else {
2511 return r;
2512 }
2513
2514 * phour = hour;
2515 * pmin = min;
2516 * psec = sec;
2517 * pzone = zone;
2518
2519 * index = cur_token;
2520
2521 return MAILIMF_NO_ERROR;
2522}
2523
2524/*
2525time-of-day = hour ":" minute [ ":" second ]
2526*/
2527
2528static int mailimf_time_of_day_parse(const char * message, size_t length,
2529 size_t * index,
2530 int * phour, int * pmin,
2531 int * psec)
2532{
2533 int hour;
2534 int min;
2535 int sec;
2536 size_t cur_token;
2537 int r;
2538
2539 cur_token = * index;
2540
2541 r = mailimf_hour_parse(message, length, &cur_token, &hour);
2542 if (r != MAILIMF_NO_ERROR)
2543 return r;
2544
2545 r = mailimf_colon_parse(message, length, &cur_token);
2546 if (r != MAILIMF_NO_ERROR)
2547 return r;
2548
2549 r = mailimf_minute_parse(message, length, &cur_token, &min);
2550 if (r != MAILIMF_NO_ERROR)
2551 return r;
2552
2553 r = mailimf_colon_parse(message, length, &cur_token);
2554 if (r == MAILIMF_NO_ERROR) {
2555 r = mailimf_second_parse(message, length, &cur_token, &sec);
2556 if (r != MAILIMF_NO_ERROR)
2557 return r;
2558 }
2559 else if (r == MAILIMF_ERROR_PARSE)
2560 sec = 0;
2561 else
2562 return r;
2563
2564 * phour = hour;
2565 * pmin = min;
2566 * psec = sec;
2567 * index = cur_token;
2568
2569 return MAILIMF_NO_ERROR;
2570}
2571
2572/*
2573hour = 2DIGIT / obs-hour
2574*/
2575
2576static int mailimf_hour_parse(const char * message, size_t length,
2577 size_t * index, int * result)
2578{
2579 uint32_t hour;
2580 int r;
2581
2582 r = mailimf_number_parse(message, length, index, &hour);
2583 if (r != MAILIMF_NO_ERROR)
2584 return r;
2585
2586 * result = hour;
2587
2588 return MAILIMF_NO_ERROR;
2589}
2590
2591/*
2592minute = 2DIGIT / obs-minute
2593*/
2594
2595static int mailimf_minute_parse(const char * message, size_t length,
2596 size_t * index, int * result)
2597{
2598 uint32_t minute;
2599 int r;
2600
2601 r = mailimf_number_parse(message, length, index, &minute);
2602 if (r != MAILIMF_NO_ERROR)
2603 return r;
2604
2605 * result = minute;
2606
2607 return MAILIMF_NO_ERROR;
2608}
2609
2610/*
2611second = 2DIGIT / obs-second
2612*/
2613
2614static int mailimf_second_parse(const char * message, size_t length,
2615 size_t * index, int * result)
2616{
2617 uint32_t second;
2618 int r;
2619
2620 r = mailimf_number_parse(message, length, index, &second);
2621 if (r != MAILIMF_NO_ERROR)
2622 return r;
2623
2624 * result = second;
2625
2626 return MAILIMF_NO_ERROR;
2627}
2628
2629/*
2630zone = (( "+" / "-" ) 4DIGIT) / obs-zone
2631*/
2632
2633/*
2634obs-zone = "UT" / "GMT" / ; Universal Time
2635 ; North American UT
2636 ; offsets
2637 "EST" / "EDT" / ; Eastern: - 5/ - 4
2638 "CST" / "CDT" / ; Central: - 6/ - 5
2639 "MST" / "MDT" / ; Mountain: - 7/ - 6
2640 "PST" / "PDT" / ; Pacific: - 8/ - 7
2641
2642 %d65-73 / ; Military zones - "A"
2643 %d75-90 / ; through "I" and "K"
2644 %d97-105 / ; through "Z", both
2645 %d107-122 ; upper and lower case
2646*/
2647
2648enum {
2649 STATE_ZONE_1 = 0,
2650 STATE_ZONE_2 = 1,
2651 STATE_ZONE_3 = 2,
2652 STATE_ZONE_OK = 3,
2653 STATE_ZONE_ERR = 4,
2654 STATE_ZONE_CONT = 5,
2655};
2656
2657static int mailimf_zone_parse(const char * message, size_t length,
2658 size_t * index, int * result)
2659{
2660 uint32_t zone;
2661 int sign;
2662 size_t cur_token;
2663 int r;
2664
2665 cur_token = * index;
2666
2667 if (cur_token + 1 < length) {
2668 if ((message[cur_token] == 'U') && (message[cur_token] == 'T')) {
2669 * result = TRUE;
2670 * index = cur_token + 2;
2671
2672 return MAILIMF_NO_ERROR;
2673 }
2674 }
2675
2676 if (cur_token + 2 < length) {
2677 int state;
2678
2679 state = STATE_ZONE_1;
2680
2681 while (state <= 2) {
2682 switch (state) {
2683 case STATE_ZONE_1:
2684 switch (message[cur_token]) {
2685 case 'G':
2686 if (message[cur_token + 1] == 'M' && message[cur_token + 2] == 'T') {
2687 zone = 0;
2688 state = STATE_ZONE_OK;
2689 }
2690 else {
2691 state = STATE_ZONE_ERR;
2692 }
2693 break;
2694 case 'E':
2695 zone = -5;
2696 state = STATE_ZONE_2;
2697 break;
2698 case 'C':
2699 zone = -6;
2700 state = STATE_ZONE_2;
2701 break;
2702 case 'M':
2703 zone = -7;
2704 state = STATE_ZONE_2;
2705 break;
2706 case 'P':
2707 zone = -8;
2708 state = STATE_ZONE_2;
2709 break;
2710 default:
2711 state = STATE_ZONE_CONT;
2712 break;
2713 }
2714 break;
2715 case STATE_ZONE_2:
2716 switch (message[cur_token + 1]) {
2717 case 'S':
2718 state = STATE_ZONE_3;
2719 break;
2720 case 'D':
2721 zone ++;
2722 state = STATE_ZONE_3;
2723 break;
2724 default:
2725 state = STATE_ZONE_ERR;
2726 break;
2727 }
2728 break;
2729 case STATE_ZONE_3:
2730 if (message[cur_token + 2] == 'T') {
2731 zone *= 100;
2732 state = STATE_ZONE_OK;
2733 }
2734 else
2735 state = STATE_ZONE_ERR;
2736 break;
2737 }
2738 }
2739
2740 switch (state) {
2741 case STATE_ZONE_OK:
2742 * result = zone;
2743 * index = cur_token + 3;
2744 return MAILIMF_NO_ERROR;
2745
2746 case STATE_ZONE_ERR:
2747 return MAILIMF_ERROR_PARSE;
2748 }
2749 }
2750
2751 sign = 1;
2752 r = mailimf_plus_parse(message, length, &cur_token);
2753 if (r == MAILIMF_NO_ERROR)
2754 sign = 1;
2755
2756 if (r == MAILIMF_ERROR_PARSE) {
2757 r = mailimf_minus_parse(message, length, &cur_token);
2758 if (r == MAILIMF_NO_ERROR)
2759 sign = -1;
2760 }
2761
2762 if (r == MAILIMF_NO_ERROR) {
2763 /* do nothing */
2764 }
2765 else if (r == MAILIMF_ERROR_PARSE)
2766 sign = 1;
2767 else
2768 return r;
2769
2770 r = mailimf_number_parse(message, length, &cur_token, &zone);
2771 if (r != MAILIMF_NO_ERROR)
2772 return r;
2773
2774 zone = zone * sign;
2775
2776 * index = cur_token;
2777 * result = zone;
2778
2779 return MAILIMF_NO_ERROR;
2780}
2781
2782/*
2783address = mailbox / group
2784*/
2785
2786int mailimf_address_parse(const char * message, size_t length,
2787 size_t * index,
2788 struct mailimf_address ** result)
2789{
2790 int type;
2791 size_t cur_token;
2792 struct mailimf_mailbox * mailbox;
2793 struct mailimf_group * group;
2794 struct mailimf_address * address;
2795 int r;
2796 int res;
2797
2798 cur_token = * index;
2799
2800 mailbox = NULL;
2801 group = NULL;
2802
2803 type = MAILIMF_ADDRESS_ERROR; /* XXX - removes a gcc warning */
2804 r = mailimf_group_parse(message, length, &cur_token, &group);
2805 if (r == MAILIMF_NO_ERROR)
2806 type = MAILIMF_ADDRESS_GROUP;
2807
2808 if (r == MAILIMF_ERROR_PARSE) {
2809 r = mailimf_mailbox_parse(message, length, &cur_token, &mailbox);
2810 if (r == MAILIMF_NO_ERROR)
2811 type = MAILIMF_ADDRESS_MAILBOX;
2812 }
2813
2814 if (r != MAILIMF_NO_ERROR) {
2815 res = r;
2816 goto err;
2817 }
2818
2819 address = mailimf_address_new(type, mailbox, group);
2820 if (address == NULL) {
2821 res = MAILIMF_ERROR_MEMORY;
2822 goto free;
2823 }
2824
2825 * result = address;
2826 * index = cur_token;
2827
2828 return MAILIMF_NO_ERROR;
2829
2830 free:
2831 if (mailbox != NULL)
2832 mailimf_mailbox_free(mailbox);
2833 if (group != NULL)
2834 mailimf_group_free(group);
2835 err:
2836 return res;
2837}
2838
2839
2840/*
2841mailbox = name-addr / addr-spec
2842*/
2843
2844
2845int mailimf_mailbox_parse(const char * message, size_t length,
2846 size_t * index,
2847 struct mailimf_mailbox ** result)
2848{
2849 size_t cur_token;
2850 char * display_name;
2851 struct mailimf_mailbox * mailbox;
2852 char * addr_spec;
2853 int r;
2854 int res;
2855
2856 cur_token = * index;
2857 display_name = NULL;
2858 addr_spec = NULL;
2859
2860 r = mailimf_name_addr_parse(message, length, &cur_token,
2861 &display_name, &addr_spec);
2862 if (r == MAILIMF_ERROR_PARSE)
2863 r = mailimf_addr_spec_parse(message, length, &cur_token, &addr_spec);
2864
2865 if (r != MAILIMF_NO_ERROR) {
2866 res = r;
2867 goto err;
2868 }
2869
2870 mailbox = mailimf_mailbox_new(display_name, addr_spec);
2871 if (mailbox == NULL) {
2872 res = MAILIMF_ERROR_MEMORY;
2873 goto free;
2874 }
2875
2876 * result = mailbox;
2877 * index = cur_token;
2878
2879 return MAILIMF_NO_ERROR;
2880
2881 free:
2882 if (display_name != NULL)
2883 mailimf_display_name_free(display_name);
2884 if (addr_spec != NULL)
2885 mailimf_addr_spec_free(addr_spec);
2886 err:
2887 return res;
2888}
2889
2890/*
2891name-addr = [display-name] angle-addr
2892*/
2893
2894static int mailimf_name_addr_parse(const char * message, size_t length,
2895 size_t * index,
2896 char ** pdisplay_name,
2897 char ** pangle_addr)
2898{
2899 char * display_name;
2900 char * angle_addr;
2901 size_t cur_token;
2902 int r;
2903 int res;
2904
2905 cur_token = * index;
2906
2907 display_name = NULL;
2908 angle_addr = NULL;
2909
2910 r = mailimf_display_name_parse(message, length, &cur_token, &display_name);
2911 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
2912 res = r;
2913 goto err;
2914 }
2915
2916 r = mailimf_angle_addr_parse(message, length, &cur_token, &angle_addr);
2917 if (r != MAILIMF_NO_ERROR) {
2918 res = r;
2919 goto free_display_name;
2920 }
2921
2922 * pdisplay_name = display_name;
2923 * pangle_addr = angle_addr;
2924 * index = cur_token;
2925
2926 return MAILIMF_NO_ERROR;
2927
2928 free_display_name:
2929 if (display_name != NULL)
2930 mailimf_display_name_free(display_name);
2931 err:
2932 return res;
2933}
2934
2935/*
2936angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr
2937*/
2938
2939static int mailimf_angle_addr_parse(const char * message, size_t length,
2940 size_t * index, char ** result)
2941{
2942 size_t cur_token;
2943 char * addr_spec;
2944 int r;
2945
2946 cur_token = * index;
2947
2948 r = mailimf_cfws_parse(message, length, &cur_token);
2949 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
2950 return r;
2951
2952 r = mailimf_lower_parse(message, length, &cur_token);
2953 if (r != MAILIMF_NO_ERROR)
2954 return r;
2955
2956 r = mailimf_addr_spec_parse(message, length, &cur_token, &addr_spec);
2957 if (r != MAILIMF_NO_ERROR)
2958 return r;
2959
2960 r = mailimf_greater_parse(message, length, &cur_token);
2961 if (r != MAILIMF_NO_ERROR) {
2962 free(addr_spec);
2963 return r;
2964 }
2965
2966 * result = addr_spec;
2967 * index = cur_token;
2968
2969 return MAILIMF_NO_ERROR;
2970}
2971
2972/*
2973group = display-name ":" [mailbox-list / CFWS] ";"
2974 [CFWS]
2975*/
2976
2977static int mailimf_group_parse(const char * message, size_t length,
2978 size_t * index,
2979 struct mailimf_group ** result)
2980{
2981 size_t cur_token;
2982 char * display_name;
2983 struct mailimf_mailbox_list * mailbox_list;
2984 struct mailimf_group * group;
2985 int r;
2986 int res;
2987
2988 cur_token = * index;
2989
2990 mailbox_list = NULL;
2991
2992 r = mailimf_display_name_parse(message, length, &cur_token, &display_name);
2993 if (r != MAILIMF_NO_ERROR) {
2994 res = r;
2995 goto err;
2996 }
2997
2998 r = mailimf_colon_parse(message, length, &cur_token);
2999 if (r != MAILIMF_NO_ERROR) {
3000 res = r;
3001 goto free_display_name;
3002 }
3003
3004 r = mailimf_mailbox_list_parse(message, length, &cur_token, &mailbox_list);
3005 switch (r) {
3006 case MAILIMF_NO_ERROR:
3007 break;
3008 case MAILIMF_ERROR_PARSE:
3009 r = mailimf_cfws_parse(message, length, &cur_token);
3010 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
3011 return r;
3012 break;
3013 default:
3014 return r;
3015 }
3016
3017 r = mailimf_semi_colon_parse(message, length, &cur_token);
3018 if (r != MAILIMF_NO_ERROR) {
3019 res = r;
3020 goto free_mailbox_list;
3021 }
3022
3023 group = mailimf_group_new(display_name, mailbox_list);
3024 if (group == NULL) {
3025 res = MAILIMF_ERROR_MEMORY;
3026 goto free_mailbox_list;
3027 }
3028
3029 * index = cur_token;
3030 * result = group;
3031
3032 return MAILIMF_NO_ERROR;
3033
3034 free_mailbox_list:
3035 mailimf_mailbox_list_free(mailbox_list);
3036 free_display_name:
3037 mailimf_display_name_free(display_name);
3038 err:
3039 return res;
3040}
3041
3042/*
3043display-name = phrase
3044*/
3045
3046static int mailimf_display_name_parse(const char * message, size_t length,
3047 size_t * index, char ** result)
3048{
3049 return mailimf_phrase_parse(message, length, index, result);
3050}
3051
3052/*
3053mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list
3054*/
3055
3056int
3057mailimf_mailbox_list_parse(const char * message, size_t length,
3058 size_t * index,
3059 struct mailimf_mailbox_list ** result)
3060{
3061 size_t cur_token;
3062 clist * list;
3063 struct mailimf_mailbox_list * mailbox_list;
3064 int r;
3065 int res;
3066
3067 cur_token = * index;
3068
3069 r = mailimf_struct_list_parse(message, length,
3070 &cur_token, &list, ',',
3071 (mailimf_struct_parser *)
3072 mailimf_mailbox_parse,
3073 (mailimf_struct_destructor *)
3074 mailimf_mailbox_free);
3075 if (r != MAILIMF_NO_ERROR) {
3076 res = r;
3077 goto err;
3078 }
3079
3080 mailbox_list = mailimf_mailbox_list_new(list);
3081 if (mailbox_list == NULL) {
3082 res = MAILIMF_ERROR_MEMORY;
3083 goto free_list;
3084 }
3085
3086 * result = mailbox_list;
3087 * index = cur_token;
3088
3089 return MAILIMF_NO_ERROR;
3090
3091 free_list:
3092 clist_foreach(list, (clist_func) mailimf_mailbox_free, NULL);
3093 clist_free(list);
3094 err:
3095 return res;
3096 }
3097
3098/*
3099address-list = (address *("," address)) / obs-addr-list
3100*/
3101
3102
3103int
3104mailimf_address_list_parse(const char * message, size_t length,
3105 size_t * index,
3106 struct mailimf_address_list ** result)
3107{
3108 size_t cur_token;
3109 clist * list;
3110 struct mailimf_address_list * address_list;
3111 int r;
3112 int res;
3113
3114 cur_token = * index;
3115
3116 r = mailimf_struct_list_parse(message, length,
3117 &cur_token, &list, ',',
3118 (mailimf_struct_parser *)
3119 mailimf_address_parse,
3120 (mailimf_struct_destructor *)
3121 mailimf_address_free);
3122 if (r != MAILIMF_NO_ERROR) {
3123 res = r;
3124 goto err;
3125 }
3126
3127 address_list = mailimf_address_list_new(list);
3128 if (address_list == NULL) {
3129 res = MAILIMF_ERROR_MEMORY;
3130 goto free_list;
3131 }
3132
3133 * result = address_list;
3134 * index = cur_token;
3135
3136 return MAILIMF_NO_ERROR;
3137
3138 free_list:
3139 clist_foreach(list, (clist_func) mailimf_address_free, NULL);
3140 clist_free(list);
3141 err:
3142 return res;
3143 }
3144
3145/*
3146addr-spec = local-part "@" domain
3147*/
3148
3149
3150static int mailimf_addr_spec_parse(const char * message, size_t length,
3151 size_t * index,
3152 char ** result)
3153{
3154 size_t cur_token;
3155#if 0
3156 char * local_part;
3157 char * domain;
3158#endif
3159 char * addr_spec;
3160 int r;
3161 int res;
3162 size_t begin;
3163 size_t end;
3164 int final;
3165 size_t count;
3166 const char * src;
3167 char * dest;
3168 size_t i;
3169
3170 cur_token = * index;
3171
3172 r = mailimf_cfws_parse(message, length, &cur_token);
3173 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
3174 res = r;
3175 goto err;
3176 }
3177
3178 end = cur_token;
3179 if (end >= length) {
3180 res = MAILIMF_ERROR_PARSE;
3181 goto err;
3182 }
3183
3184 begin = cur_token;
3185
3186 final = FALSE;
3187 while (1) {
3188 switch (message[end]) {
3189 case '>':
3190 case ',':
3191 case '\r':
3192 case '\n':
3193 case '(':
3194 case ')':
3195 case ':':
3196 case ';':
3197 final = TRUE;
3198 break;
3199 }
3200
3201 if (final)
3202 break;
3203
3204 end ++;
3205 if (end >= length)
3206 break;
3207 }
3208
3209 if (end == begin) {
3210 res = MAILIMF_ERROR_PARSE;
3211 goto err;
3212 }
3213
3214 addr_spec = malloc(end - cur_token + 1);
3215 if (addr_spec == NULL) {
3216 res = MAILIMF_ERROR_MEMORY;
3217 goto err;
3218 }
3219
3220 count = end - cur_token;
3221 src = message + cur_token;
3222 dest = addr_spec;
3223 for(i = 0 ; i < count ; i ++) {
3224 if ((* src != ' ') && (* src != '\t')) {
3225 * dest = * src;
3226 dest ++;
3227 }
3228 src ++;
3229 }
3230 * dest = '\0';
3231
3232#if 0
3233 strncpy(addr_spec, message + cur_token, end - cur_token);
3234 addr_spec[end - cur_token] = '\0';
3235#endif
3236
3237 cur_token = end;
3238
3239#if 0
3240 r = mailimf_local_part_parse(message, length, &cur_token, &local_part);
3241 if (r != MAILIMF_NO_ERROR) {
3242 res = r;
3243 goto err;
3244 }
3245
3246 r = mailimf_at_sign_parse(message, length, &cur_token);
3247 switch (r) {
3248 case MAILIMF_NO_ERROR:
3249 r = mailimf_domain_parse(message, length, &cur_token, &domain);
3250 if (r != MAILIMF_NO_ERROR) {
3251 res = r;
3252 goto free_local_part;
3253 }
3254 break;
3255
3256 case MAILIMF_ERROR_PARSE:
3257 domain = NULL;
3258 break;
3259
3260 default:
3261 res = r;
3262 goto free_local_part;
3263 }
3264
3265 if (domain) {
3266 addr_spec = malloc(strlen(local_part) + strlen(domain) + 2);
3267 if (addr_spec == NULL) {
3268 res = MAILIMF_ERROR_MEMORY;
3269 goto free_domain;
3270 }
3271
3272 strcpy(addr_spec, local_part);
3273 strcat(addr_spec, "@");
3274 strcat(addr_spec, domain);
3275
3276 mailimf_domain_free(domain);
3277 mailimf_local_part_free(local_part);
3278 }
3279 else {
3280 addr_spec = local_part;
3281 }
3282#endif
3283
3284 * result = addr_spec;
3285 * index = cur_token;
3286
3287 return MAILIMF_NO_ERROR;
3288
3289#if 0
3290 free_domain:
3291 mailimf_domain_free(domain);
3292 free_local_part:
3293 mailimf_local_part_free(local_part);
3294#endif
3295 err:
3296 return res;
3297}
3298
3299/*
3300local-part = dot-atom / quoted-string / obs-local-part
3301*/
3302
3303#if 0
3304static int mailimf_local_part_parse(const char * message, size_t length,
3305 size_t * index,
3306 char ** result)
3307{
3308 int r;
3309
3310 r = mailimf_dot_atom_parse(message, length, index, result);
3311 switch (r) {
3312 case MAILIMF_NO_ERROR:
3313 return r;
3314 case MAILIMF_ERROR_PARSE:
3315 break;
3316 default:
3317 return r;
3318 }
3319
3320 r = mailimf_quoted_string_parse(message, length, index, result);
3321 if (r != MAILIMF_NO_ERROR)
3322 return r;
3323
3324 return MAILIMF_NO_ERROR;
3325}
3326#endif
3327
3328/*
3329domain = dot-atom / domain-literal / obs-domain
3330*/
3331
3332#if 0
3333static int mailimf_domain_parse(const char * message, size_t length,
3334 size_t * index,
3335 char ** result)
3336{
3337 int r;
3338
3339 r = mailimf_dot_atom_parse(message, length, index, result);
3340 switch (r) {
3341 case MAILIMF_NO_ERROR:
3342 return r;
3343 case MAILIMF_ERROR_PARSE:
3344 break;
3345 default:
3346 return r;
3347 }
3348
3349 r = mailimf_domain_literal_parse(message, length, index, result);
3350 if (r != MAILIMF_NO_ERROR)
3351 return r;
3352
3353 return MAILIMF_NO_ERROR;
3354}
3355#endif
3356
3357/*
3358[FWS] dcontent
3359*/
3360
3361#if 0
3362static int
3363mailimf_domain_literal_fws_dcontent_parse(const char * message, size_t length,
3364 size_t * index)
3365{
3366 size_t cur_token;
3367 char ch;
3368 int r;
3369
3370 cur_token = * index;
3371
3372 r = mailimf_cfws_parse(message, length, &cur_token);
3373 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
3374 return r;
3375
3376 r = mailimf_dcontent_parse(message, length, &cur_token, &ch);
3377 if (r != MAILIMF_NO_ERROR)
3378 return r;
3379
3380 * index = cur_token;
3381
3382 return MAILIMF_NO_ERROR;
3383}
3384#endif
3385
3386/*
3387domain-literal = [CFWS] "[" *([FWS] dcontent) [FWS] "]" [CFWS]
3388*/
3389
3390#if 0
3391static int mailimf_domain_literal_parse(const char * message, size_t length,
3392 size_t * index, char ** result)
3393{
3394 size_t cur_token;
3395 int len;
3396 int begin;
3397 char * domain_literal;
3398 int r;
3399
3400 cur_token = * index;
3401
3402 r = mailimf_cfws_parse(message, length, &cur_token);
3403 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
3404 return r;
3405
3406 begin = cur_token;
3407 r = mailimf_obracket_parse(message, length, &cur_token);
3408 if (r != MAILIMF_NO_ERROR)
3409 return r;
3410
3411 while (1) {
3412 r = mailimf_domain_literal_fws_dcontent_parse(message, length,
3413 &cur_token);
3414 if (r == MAILIMF_NO_ERROR) {
3415 /* do nothing */
3416 }
3417 else if (r == MAILIMF_ERROR_PARSE)
3418 break;
3419 else
3420 return r;
3421 }
3422
3423 r = mailimf_fws_parse(message, length, &cur_token);
3424 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
3425 return r;
3426
3427 r = mailimf_cbracket_parse(message, length, &cur_token);
3428 if (r != MAILIMF_NO_ERROR)
3429 return r;
3430
3431 len = cur_token - begin;
3432
3433 domain_literal = malloc(len + 1);
3434 if (domain_literal == NULL)
3435 return MAILIMF_ERROR_MEMORY;
3436 strncpy(domain_literal, message + begin, len);
3437 domain_literal[len] = '\0';
3438
3439 * result = domain_literal;
3440 * index = cur_token;
3441
3442 return MAILIMF_NO_ERROR;
3443}
3444#endif
3445
3446/*
3447dcontent = dtext / quoted-pair
3448*/
3449
3450#if 0
3451static int mailimf_dcontent_parse(const char * message, size_t length,
3452 size_t * index, char * result)
3453{
3454 size_t cur_token;
3455 char ch;
3456 int r;
3457
3458 cur_token = * index;
3459
3460 if (cur_token >= length)
3461 return MAILIMF_ERROR_PARSE;
3462
3463 if (is_dtext(message[cur_token])) {
3464 ch = message[cur_token];
3465 cur_token ++;
3466 }
3467 else {
3468 r = mailimf_quoted_pair_parse(message, length, &cur_token, &ch);
3469
3470 if (r != MAILIMF_NO_ERROR)
3471 return r;
3472 }
3473
3474 * index = cur_token;
3475 * result = ch;
3476
3477 return MAILIMF_NO_ERROR;
3478}
3479#endif
3480
3481
3482/*
3483dtext = NO-WS-CTL / ; Non white space controls
3484
3485 %d33-90 / ; The rest of the US-ASCII
3486 %d94-126 ; characters not including "[",
3487 ; "]", or "\"
3488*/
3489
3490static inline int is_dtext(char ch)
3491{
3492 unsigned char uch = (unsigned char) ch;
3493
3494 if (is_no_ws_ctl(ch))
3495 return TRUE;
3496
3497 if (uch < 33)
3498 return FALSE;
3499
3500 if ((uch >= 91) && (uch <= 93))
3501 return FALSE;
3502
3503 if (uch == 127)
3504 return FALSE;
3505
3506 return TRUE;
3507}
3508
3509/*
3510message = (fields / obs-fields)
3511 [CRLF body]
3512*/
3513
3514int mailimf_message_parse(const char * message, size_t length,
3515 size_t * index,
3516 struct mailimf_message ** result)
3517{
3518 struct mailimf_fields * fields;
3519 struct mailimf_body * body;
3520 struct mailimf_message * msg;
3521 size_t cur_token;
3522 int r;
3523 int res;
3524
3525 cur_token = * index;
3526
3527 r = mailimf_fields_parse(message, length, &cur_token, &fields);
3528 if (r != MAILIMF_NO_ERROR) {
3529 res = r;
3530 goto err;
3531 }
3532
3533 r = mailimf_crlf_parse(message, length, &cur_token);
3534 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
3535 res = r;
3536 goto err;
3537 }
3538
3539 r = mailimf_body_parse(message, length, &cur_token, &body);
3540 if (r != MAILIMF_NO_ERROR) {
3541 res = r;
3542 goto free_fields;
3543 }
3544
3545 msg = mailimf_message_new(fields, body);
3546 if (msg == NULL) {
3547 res = MAILIMF_ERROR_MEMORY;
3548 goto free_body;
3549 }
3550
3551 * index = cur_token;
3552 * result = msg;
3553
3554 return MAILIMF_NO_ERROR;
3555
3556 free_body:
3557 mailimf_body_free(body);
3558 free_fields:
3559 mailimf_fields_free(fields);
3560 err:
3561 return res;
3562}
3563
3564/*
3565body = *(*998text CRLF) *998text
3566*/
3567
3568int mailimf_body_parse(const char * message, size_t length,
3569 size_t * index,
3570 struct mailimf_body ** result)
3571{
3572 size_t cur_token;
3573 struct mailimf_body * body;
3574
3575 cur_token = * index;
3576
3577 body = mailimf_body_new(message + cur_token, length - cur_token);
3578 if (body == NULL)
3579 return MAILIMF_ERROR_MEMORY;
3580
3581 cur_token = length;
3582
3583 * result = body;
3584 * index = cur_token;
3585
3586 return MAILIMF_NO_ERROR;
3587}
3588
3589/*
3590CHANGE TO THE RFC 2822
3591
3592original :
3593
3594fields = *(trace
3595 *(resent-date /
3596 resent-from /
3597 resent-sender /
3598 resent-to /
3599 resent-cc /
3600 resent-bcc /
3601 resent-msg-id))
3602 *(orig-date /
3603 from /
3604 sender /
3605 reply-to /
3606 to /
3607 cc /
3608 bcc /
3609 message-id /
3610 in-reply-to /
3611 references /
3612 subject /
3613 comments /
3614 keywords /
3615 optional-field)
3616
3617INTO THE FOLLOWING :
3618*/
3619
3620/*
3621resent-fields-list = *(resent-date /
3622 resent-from /
3623 resent-sender /
3624 resent-to /
3625 resent-cc /
3626 resent-bcc /
3627 resent-msg-id))
3628*/
3629
3630#if 0
3631enum {
3632 RESENT_HEADER_START,
3633};
3634
3635static int guess_resent_header_type(char * message,
3636 size_t length, size_t index)
3637{
3638 int r;
3639
3640 r = mailimf_token_case_insensitive_parse(message,
3641 length, &index, "Resent-");
3642 if (r != MAILIMF_NO_ERROR)
3643 return MAILIMF_RESENT_FIELD_NONE;
3644
3645 if (index >= length)
3646 return MAILIMF_RESENT_FIELD_NONE;
3647
3648 switch(toupper(message[index])) {
3649 case 'D':
3650 return MAILIMF_RESENT_FIELD_DATE;
3651 case 'F':
3652 return MAILIMF_RESENT_FIELD_FROM;
3653 case 'S':
3654 return MAILIMF_RESENT_FIELD_SENDER;
3655 case 'T':
3656 return MAILIMF_RESENT_FIELD_TO;
3657 case 'C':
3658 return MAILIMF_RESENT_FIELD_CC;
3659 case 'B':
3660 return MAILIMF_RESENT_FIELD_BCC;
3661 case 'M':
3662 return MAILIMF_RESENT_FIELD_MSG_ID;
3663 default:
3664 return MAILIMF_RESENT_FIELD_NONE;
3665 }
3666}
3667#endif
3668
3669#if 0
3670static int
3671mailimf_resent_field_parse(const char * message, size_t length,
3672 size_t * index,
3673 struct mailimf_resent_field ** result)
3674{
3675 struct mailimf_orig_date * resent_date;
3676 struct mailimf_from * resent_from;
3677 struct mailimf_sender * resent_sender;
3678 struct mailimf_to* resent_to;
3679 struct mailimf_cc * resent_cc;
3680 struct mailimf_bcc * resent_bcc;
3681 struct mailimf_message_id * resent_msg_id;
3682 size_t cur_token;
3683 int type;
3684 struct mailimf_resent_field * resent_field;
3685 int r;
3686 int res;
3687
3688 cur_token = * index;
3689
3690 resent_date = NULL;
3691 resent_from = NULL;
3692 resent_sender = NULL;
3693 resent_to = NULL;
3694 resent_cc = NULL;
3695 resent_bcc = NULL;
3696 resent_msg_id = NULL;
3697
3698 type = guess_resent_header_type(message, length, cur_token);
3699
3700 switch(type) {
3701 case MAILIMF_RESENT_FIELD_DATE:
3702 r = mailimf_resent_date_parse(message, length, &cur_token,
3703 &resent_date);
3704 if (r != MAILIMF_NO_ERROR) {
3705 res = r;
3706 goto err;
3707 }
3708 break;
3709 case MAILIMF_RESENT_FIELD_FROM:
3710 r = mailimf_resent_from_parse(message, length, &cur_token,
3711 &resent_from);
3712 if (r != MAILIMF_NO_ERROR) {
3713 res = r;
3714 goto err;
3715 }
3716 break;
3717 case MAILIMF_RESENT_FIELD_SENDER:
3718 r = mailimf_resent_sender_parse(message, length, &cur_token,
3719 &resent_sender);
3720 if (r != MAILIMF_NO_ERROR) {
3721 res = r;
3722 goto err;
3723 }
3724 break;
3725 case MAILIMF_RESENT_FIELD_TO:
3726 r = mailimf_resent_to_parse(message, length, &cur_token,
3727 &resent_to);
3728 if (r != MAILIMF_NO_ERROR) {
3729 res = r;
3730 goto err;
3731 }
3732 break;
3733 case MAILIMF_RESENT_FIELD_CC:
3734 r= mailimf_resent_cc_parse(message, length, &cur_token,
3735 &resent_cc);
3736 if (r != MAILIMF_NO_ERROR) {
3737 res = r;
3738 goto err;
3739 }
3740 break;
3741 case MAILIMF_RESENT_FIELD_BCC:
3742 r = mailimf_resent_bcc_parse(message, length, &cur_token,
3743 &resent_bcc);
3744 if (r != MAILIMF_NO_ERROR) {
3745 res = r;
3746 goto err;
3747 }
3748 break;
3749 case MAILIMF_RESENT_FIELD_MSG_ID:
3750 r = mailimf_resent_msg_id_parse(message, length, &cur_token,
3751 &resent_msg_id);
3752 if (r != MAILIMF_NO_ERROR) {
3753 res = r;
3754 goto err;
3755 }
3756 break;
3757 default:
3758 res = MAILIMF_ERROR_PARSE;
3759 goto err;
3760 }
3761
3762 resent_field = mailimf_resent_field_new(type, resent_date,
3763 resent_from, resent_sender,
3764 resent_to, resent_cc,
3765 resent_bcc, resent_msg_id);
3766 if (resent_field == NULL) {
3767 res = MAILIMF_ERROR_MEMORY;
3768 goto free_resent;
3769 }
3770
3771 * result = resent_field;
3772 * index = cur_token;
3773
3774 return MAILIMF_NO_ERROR;
3775
3776 free_resent:
3777 if (resent_msg_id != NULL)
3778 mailimf_message_id_free(resent_msg_id);
3779 if (resent_bcc != NULL)
3780 mailimf_bcc_free(resent_bcc);
3781 if (resent_cc != NULL)
3782 mailimf_cc_free(resent_cc);
3783 if (resent_to != NULL)
3784 mailimf_to_free(resent_to);
3785 if (resent_sender != NULL)
3786 mailimf_sender_free(resent_sender);
3787 if (resent_from != NULL)
3788 mailimf_from_free(resent_from);
3789 if (resent_date != NULL)
3790 mailimf_orig_date_free(resent_date);
3791 err:
3792 return res;
3793}
3794#endif
3795
3796#if 0
3797static int
3798mailimf_resent_fields_list_parse(const char * message, size_t length,
3799 size_t * index,
3800 struct mailimf_resent_fields_list ** result)
3801{
3802 clist * list;
3803 size_t cur_token;
3804 struct mailimf_resent_fields_list * resent_fields_list;
3805 int r;
3806 int res;
3807
3808 cur_token = * index;
3809 list = NULL;
3810
3811 r = mailimf_struct_multiple_parse(message, length, &cur_token, &list,
3812 (mailimf_struct_parser *)
3813 mailimf_resent_field_parse,
3814 (mailimf_struct_destructor *)
3815 mailimf_resent_field_free);
3816 if (r != MAILIMF_NO_ERROR) {
3817 res = r;
3818 goto err;
3819 }
3820
3821 resent_fields_list = mailimf_resent_fields_list_new(list);
3822 if (resent_fields_list == NULL) {
3823 res = MAILIMF_ERROR_MEMORY;
3824 goto free_list;
3825 }
3826
3827 * result = resent_fields_list;
3828 * index = cur_token;
3829
3830 return MAILIMF_NO_ERROR;
3831
3832 free_list:
3833 clist_foreach(list, (clist_func) mailimf_resent_field_free, NULL);
3834 clist_free(list);
3835 err:
3836 return res;
3837}
3838#endif
3839
3840/*
3841 ([trace]
3842 [resent-fields-list])
3843*/
3844
3845#if 0
3846static int
3847mailimf_trace_resent_fields_parse(const char * message, size_t length,
3848 size_t * index,
3849 struct mailimf_trace_resent_fields ** result)
3850{
3851 size_t cur_token;
3852 struct mailimf_return * return_path;
3853 struct mailimf_resent_fields_list * resent_fields;
3854 struct mailimf_trace_resent_fields * trace_resent_fields;
3855 int res;
3856 int r;
3857
3858 cur_token = * index;
3859
3860 return_path = NULL;
3861 resent_fields = NULL;
3862
3863 r = mailimf_return_parse(message, length, &cur_token,
3864 &return_path);
3865 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
3866 res = r;
3867 goto err;
3868 }
3869
3870 r = mailimf_resent_fields_list_parse(message, length, &cur_token,
3871 &resent_fields);
3872 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
3873 res = r;
3874 goto err;
3875 }
3876
3877 if ((return_path == NULL) && (resent_fields == NULL)) {
3878 res = MAILIMF_ERROR_PARSE;
3879 goto err;
3880 }
3881
3882 trace_resent_fields = mailimf_trace_resent_fields_new(return_path,
3883 resent_fields);
3884 if (trace_resent_fields == NULL) {
3885 res = MAILIMF_ERROR_MEMORY;
3886 goto free_resent_fields;
3887 }
3888
3889 * result = trace_resent_fields;
3890 * index = cur_token;
3891
3892 return MAILIMF_NO_ERROR;
3893
3894 free_resent_fields:
3895 if (resent_fields != NULL)
3896 mailimf_resent_fields_list_free(resent_fields);
3897 if (return_path != NULL)
3898 mailimf_return_free(return_path);
3899 err:
3900 return res;
3901}
3902#endif
3903
3904/*
3905delivering-info = *([trace]
3906 [resent-fields-list])
3907*/
3908
3909#if 0
3910static int
3911mailimf_delivering_info_parse(const char * message, size_t length,
3912 size_t * index,
3913 struct mailimf_delivering_info ** result)
3914{
3915 size_t cur_token;
3916 clist * list;
3917 struct mailimf_delivering_info * delivering_info;
3918 int r;
3919 int res;
3920
3921 cur_token = * index;
3922
3923 r = mailimf_struct_multiple_parse(message, length, &cur_token,
3924 &list,
3925 (mailimf_struct_parser *)
3926 mailimf_trace_resent_fields_parse,
3927 (mailimf_struct_destructor *)
3928 mailimf_trace_resent_fields_free);
3929 if (r != MAILIMF_NO_ERROR) {
3930 res = r;
3931 goto err;
3932 }
3933
3934 delivering_info = mailimf_delivering_info_new(list);
3935 if (delivering_info == NULL) {
3936 res = MAILIMF_ERROR_MEMORY;
3937 goto free_list;
3938 }
3939
3940 * result = delivering_info;
3941 * index = cur_token;
3942
3943 return MAILIMF_NO_ERROR;
3944
3945 free_list:
3946 clist_foreach(list, (clist_func) mailimf_trace_resent_fields_free, NULL);
3947 clist_free(list);
3948 err:
3949 return res;
3950}
3951#endif
3952
3953/*
3954field = delivering-info /
3955 orig-date /
3956 from /
3957 sender /
3958 reply-to /
3959 to /
3960 cc /
3961 bcc /
3962 message-id /
3963 in-reply-to /
3964 references /
3965 subject /
3966 comments /
3967 keywords /
3968 optional-field
3969*/
3970
3971enum {
3972 HEADER_START,
3973 HEADER_C,
3974 HEADER_R,
3975 HEADER_RE,
3976 HEADER_S,
3977 HEADER_RES,
3978};
3979
3980static int guess_header_type(const char * message, size_t length, size_t index)
3981{
3982 int state;
3983 int r;
3984
3985 state = HEADER_START;
3986
3987 while (1) {
3988
3989 if (index >= length)
3990 return MAILIMF_FIELD_NONE;
3991
3992 switch(state) {
3993 case HEADER_START:
3994 switch((char) toupper((unsigned char) message[index])) {
3995 case 'B':
3996 return MAILIMF_FIELD_BCC;
3997 case 'C':
3998 state = HEADER_C;
3999 break;
4000 case 'D':
4001 return MAILIMF_FIELD_ORIG_DATE;
4002 case 'F':
4003 return MAILIMF_FIELD_FROM;
4004 case 'I':
4005 return MAILIMF_FIELD_IN_REPLY_TO;
4006 case 'K':
4007 return MAILIMF_FIELD_KEYWORDS;
4008 case 'M':
4009 return MAILIMF_FIELD_MESSAGE_ID;
4010 case 'R':
4011 state = HEADER_R;
4012 break;
4013 case 'T':
4014 return MAILIMF_FIELD_TO;
4015 break;
4016 case 'S':
4017 state = HEADER_S;
4018 break;
4019 default:
4020 return MAILIMF_FIELD_NONE;
4021 }
4022 break;
4023 case HEADER_C:
4024 switch((char) toupper((unsigned char) message[index])) {
4025 case 'O':
4026 return MAILIMF_FIELD_COMMENTS;
4027 case 'C':
4028 return MAILIMF_FIELD_CC;
4029 default:
4030 return MAILIMF_FIELD_NONE;
4031 }
4032 break;
4033 case HEADER_R:
4034 switch((char) toupper((unsigned char) message[index])) {
4035 case 'E':
4036 state = HEADER_RE;
4037 break;
4038 default:
4039 return MAILIMF_FIELD_NONE;
4040 }
4041 break;
4042 case HEADER_RE:
4043 switch((char) toupper((unsigned char) message[index])) {
4044 case 'F':
4045 return MAILIMF_FIELD_REFERENCES;
4046 case 'P':
4047 return MAILIMF_FIELD_REPLY_TO;
4048 case 'S':
4049 state = HEADER_RES;
4050 break;
4051 case 'T':
4052 return MAILIMF_FIELD_RETURN_PATH;
4053 default:
4054 return MAILIMF_FIELD_NONE;
4055 }
4056 break;
4057 case HEADER_S:
4058 switch((char) toupper((unsigned char) message[index])) {
4059 case 'E':
4060 return MAILIMF_FIELD_SENDER;
4061 case 'U':
4062 return MAILIMF_FIELD_SUBJECT;
4063 default:
4064 return MAILIMF_FIELD_NONE;
4065 }
4066 break;
4067
4068 case HEADER_RES:
4069 r = mailimf_token_case_insensitive_parse(message,
4070 length, &index, "ent-");
4071 if (r != MAILIMF_NO_ERROR)
4072 return MAILIMF_FIELD_NONE;
4073
4074 if (index >= length)
4075 return MAILIMF_FIELD_NONE;
4076
4077 switch((char) toupper((unsigned char) message[index])) {
4078 case 'D':
4079 return MAILIMF_FIELD_RESENT_DATE;
4080 case 'F':
4081 return MAILIMF_FIELD_RESENT_FROM;
4082 case 'S':
4083 return MAILIMF_FIELD_RESENT_SENDER;
4084 case 'T':
4085 return MAILIMF_FIELD_RESENT_TO;
4086 case 'C':
4087 return MAILIMF_FIELD_RESENT_CC;
4088 case 'B':
4089 return MAILIMF_FIELD_RESENT_BCC;
4090 case 'M':
4091 return MAILIMF_FIELD_RESENT_MSG_ID;
4092 default:
4093 return MAILIMF_FIELD_NONE;
4094 }
4095 break;
4096 }
4097 index ++;
4098 }
4099}
4100
4101static int mailimf_field_parse(const char * message, size_t length,
4102 size_t * index,
4103 struct mailimf_field ** result)
4104{
4105 size_t cur_token;
4106 int type;
4107 struct mailimf_return * return_path;
4108 struct mailimf_orig_date * resent_date;
4109 struct mailimf_from * resent_from;
4110 struct mailimf_sender * resent_sender;
4111 struct mailimf_to* resent_to;
4112 struct mailimf_cc * resent_cc;
4113 struct mailimf_bcc * resent_bcc;
4114 struct mailimf_message_id * resent_msg_id;
4115 struct mailimf_orig_date * orig_date;
4116 struct mailimf_from * from;
4117 struct mailimf_sender * sender;
4118 struct mailimf_reply_to * reply_to;
4119 struct mailimf_to * to;
4120 struct mailimf_cc * cc;
4121 struct mailimf_bcc * bcc;
4122 struct mailimf_message_id * message_id;
4123 struct mailimf_in_reply_to * in_reply_to;
4124 struct mailimf_references * references;
4125 struct mailimf_subject * subject;
4126 struct mailimf_comments * comments;
4127 struct mailimf_keywords * keywords;
4128 struct mailimf_optional_field * optional_field;
4129 struct mailimf_field * field;
4130 int guessed_type;
4131 int r;
4132 int res;
4133
4134 cur_token = * index;
4135
4136 return_path = NULL;
4137 resent_date = NULL;
4138 resent_from = NULL;
4139 resent_sender = NULL;
4140 resent_to = NULL;
4141 resent_cc = NULL;
4142 resent_bcc = NULL;
4143 resent_msg_id = NULL;
4144 orig_date = NULL;
4145 from = NULL;
4146 sender = NULL;
4147 reply_to = NULL;
4148 to = NULL;
4149 cc = NULL;
4150 bcc = NULL;
4151 message_id = NULL;
4152 in_reply_to = NULL;
4153 references = NULL;
4154 subject = NULL;
4155 comments = NULL;
4156 keywords = NULL;
4157 optional_field = NULL;
4158
4159 guessed_type = guess_header_type(message, length, cur_token);
4160 type = MAILIMF_FIELD_NONE;
4161
4162 switch (guessed_type) {
4163 case MAILIMF_FIELD_ORIG_DATE:
4164 r = mailimf_orig_date_parse(message, length, &cur_token,
4165 &orig_date);
4166 if (r == MAILIMF_NO_ERROR)
4167 type = MAILIMF_FIELD_ORIG_DATE;
4168 else if (r == MAILIMF_ERROR_PARSE) {
4169 /* do nothing */
4170 }
4171 else {
4172 res = r;
4173 goto err;
4174 }
4175 break;
4176 case MAILIMF_FIELD_FROM:
4177 r = mailimf_from_parse(message, length, &cur_token,
4178 &from);
4179 if (r == MAILIMF_NO_ERROR)
4180 type = guessed_type;
4181 else if (r == MAILIMF_ERROR_PARSE) {
4182 /* do nothing */
4183 }
4184 else {
4185 res = r;
4186 goto err;
4187 }
4188 break;
4189 case MAILIMF_FIELD_SENDER:
4190 r = mailimf_sender_parse(message, length, &cur_token,
4191 &sender);
4192 if (r == MAILIMF_NO_ERROR)
4193 type = guessed_type;
4194 else if (r == MAILIMF_ERROR_PARSE) {
4195 /* do nothing */
4196 }
4197 else {
4198 res = r;
4199 goto err;
4200 }
4201 break;
4202 case MAILIMF_FIELD_REPLY_TO:
4203 r = mailimf_reply_to_parse(message, length, &cur_token,
4204 &reply_to);
4205 if (r == MAILIMF_NO_ERROR)
4206 type = guessed_type;
4207 else if (r == MAILIMF_ERROR_PARSE) {
4208 /* do nothing */
4209 }
4210 else {
4211 res = r;
4212 goto err;
4213 }
4214 break;
4215 case MAILIMF_FIELD_TO:
4216 r = mailimf_to_parse(message, length, &cur_token,
4217 &to);
4218 if (r == MAILIMF_NO_ERROR)
4219 type = guessed_type;
4220 else if (r == MAILIMF_ERROR_PARSE) {
4221 /* do nothing */
4222 }
4223 else {
4224 res = r;
4225 goto err;
4226 }
4227 break;
4228 case MAILIMF_FIELD_CC:
4229 r = mailimf_cc_parse(message, length, &cur_token,
4230 &cc);
4231 if (r == MAILIMF_NO_ERROR)
4232 type = guessed_type;
4233 else if (r == MAILIMF_ERROR_PARSE) {
4234 /* do nothing */
4235 }
4236 else {
4237 res = r;
4238 goto err;
4239 }
4240 break;
4241 case MAILIMF_FIELD_BCC:
4242 r = mailimf_bcc_parse(message, length, &cur_token,
4243 &bcc);
4244 if (r == MAILIMF_NO_ERROR)
4245 type = guessed_type;
4246 else if (r == MAILIMF_ERROR_PARSE) {
4247 /* do nothing */
4248 }
4249 else {
4250 res = r;
4251 goto err;
4252 }
4253 break;
4254 case MAILIMF_FIELD_MESSAGE_ID:
4255 r = mailimf_message_id_parse(message, length, &cur_token,
4256 &message_id);
4257 if (r == MAILIMF_NO_ERROR)
4258 type = guessed_type;
4259 else if (r == MAILIMF_ERROR_PARSE) {
4260 /* do nothing */
4261 }
4262 else {
4263 res = r;
4264 goto err;
4265 }
4266 break;
4267 case MAILIMF_FIELD_IN_REPLY_TO:
4268 r = mailimf_in_reply_to_parse(message, length, &cur_token,
4269 &in_reply_to);
4270 if (r == MAILIMF_NO_ERROR)
4271 type = guessed_type;
4272 else if (r == MAILIMF_ERROR_PARSE) {
4273 /* do nothing */
4274 }
4275 else {
4276 res = r;
4277 goto err;
4278 }
4279 break;
4280 case MAILIMF_FIELD_REFERENCES:
4281 r = mailimf_references_parse(message, length, &cur_token,
4282 &references);
4283 if (r == MAILIMF_NO_ERROR)
4284 type = guessed_type;
4285 else if (r == MAILIMF_ERROR_PARSE) {
4286 /* do nothing */
4287 }
4288 else {
4289 res = r;
4290 goto err;
4291 }
4292 break;
4293 case MAILIMF_FIELD_SUBJECT:
4294 r = mailimf_subject_parse(message, length, &cur_token,
4295 &subject);
4296 if (r == MAILIMF_NO_ERROR)
4297 type = guessed_type;
4298 else if (r == MAILIMF_ERROR_PARSE) {
4299 /* do nothing */
4300 }
4301 else {
4302 res = r;
4303 goto err;
4304 }
4305 break;
4306 case MAILIMF_FIELD_COMMENTS:
4307 r = mailimf_comments_parse(message, length, &cur_token,
4308 &comments);
4309 if (r == MAILIMF_NO_ERROR)
4310 type = guessed_type;
4311 else if (r == MAILIMF_ERROR_PARSE) {
4312 /* do nothing */
4313 }
4314 else {
4315 res = r;
4316 goto err;
4317 }
4318 break;
4319 case MAILIMF_FIELD_KEYWORDS:
4320 r = mailimf_keywords_parse(message, length, &cur_token,
4321 &keywords);
4322 if (r == MAILIMF_NO_ERROR)
4323 type = guessed_type;
4324 else if (r == MAILIMF_ERROR_PARSE) {
4325 /* do nothing */
4326 }
4327 else {
4328 res = r;
4329 goto err;
4330 }
4331 break;
4332 case MAILIMF_FIELD_RETURN_PATH:
4333 r = mailimf_return_parse(message, length, &cur_token,
4334 &return_path);
4335 if (r == MAILIMF_NO_ERROR)
4336 type = guessed_type;
4337 else if (r == MAILIMF_ERROR_PARSE) {
4338 /* do nothing */
4339 }
4340 else {
4341 res = r;
4342 goto err;
4343 }
4344 break;
4345 case MAILIMF_FIELD_RESENT_DATE:
4346 r = mailimf_resent_date_parse(message, length, &cur_token,
4347 &resent_date);
4348 if (r == MAILIMF_NO_ERROR)
4349 type = guessed_type;
4350 else if (r == MAILIMF_ERROR_PARSE) {
4351 /* do nothing */
4352 }
4353 else {
4354 res = r;
4355 goto err;
4356 }
4357 break;
4358 case MAILIMF_FIELD_RESENT_FROM:
4359 r = mailimf_resent_from_parse(message, length, &cur_token,
4360 &resent_from);
4361 if (r == MAILIMF_NO_ERROR)
4362 type = guessed_type;
4363 else if (r == MAILIMF_ERROR_PARSE) {
4364 /* do nothing */
4365 }
4366 else {
4367 res = r;
4368 goto err;
4369 }
4370 break;
4371 case MAILIMF_FIELD_RESENT_SENDER:
4372 r = mailimf_resent_sender_parse(message, length, &cur_token,
4373 &resent_sender);
4374 if (r == MAILIMF_NO_ERROR)
4375 type = guessed_type;
4376 else if (r == MAILIMF_ERROR_PARSE) {
4377 /* do nothing */
4378 }
4379 else {
4380 res = r;
4381 goto err;
4382 }
4383 break;
4384 case MAILIMF_FIELD_RESENT_TO:
4385 r = mailimf_resent_to_parse(message, length, &cur_token,
4386 &resent_to);
4387 if (r == MAILIMF_NO_ERROR)
4388 type = guessed_type;
4389 else if (r == MAILIMF_ERROR_PARSE) {
4390 /* do nothing */
4391 }
4392 else {
4393 res = r;
4394 goto err;
4395 }
4396 break;
4397 case MAILIMF_FIELD_RESENT_CC:
4398 r= mailimf_resent_cc_parse(message, length, &cur_token,
4399 &resent_cc);
4400 if (r == MAILIMF_NO_ERROR)
4401 type = guessed_type;
4402 else if (r == MAILIMF_ERROR_PARSE) {
4403 /* do nothing */
4404 }
4405 else {
4406 res = r;
4407 goto err;
4408 }
4409 break;
4410 case MAILIMF_FIELD_RESENT_BCC:
4411 r = mailimf_resent_bcc_parse(message, length, &cur_token,
4412 &resent_bcc);
4413 if (r == MAILIMF_NO_ERROR)
4414 type = guessed_type;
4415 else if (r == MAILIMF_ERROR_PARSE) {
4416 /* do nothing */
4417 }
4418 else {
4419 res = r;
4420 goto err;
4421 }
4422 break;
4423 case MAILIMF_FIELD_RESENT_MSG_ID:
4424 r = mailimf_resent_msg_id_parse(message, length, &cur_token,
4425 &resent_msg_id);
4426 if (r == MAILIMF_NO_ERROR)
4427 type = guessed_type;
4428 else if (r == MAILIMF_ERROR_PARSE) {
4429 /* do nothing */
4430 }
4431 else {
4432 res = r;
4433 goto err;
4434 }
4435 break;
4436 }
4437
4438 if (type == MAILIMF_FIELD_NONE) {
4439 r = mailimf_optional_field_parse(message, length, &cur_token,
4440 &optional_field);
4441 if (r != MAILIMF_NO_ERROR) {
4442 res = r;
4443 goto err;
4444 }
4445
4446 type = MAILIMF_FIELD_OPTIONAL_FIELD;
4447 }
4448
4449 field = mailimf_field_new(type, return_path, resent_date,
4450 resent_from, resent_sender, resent_to, resent_cc, resent_bcc,
4451 resent_msg_id, orig_date, from, sender, reply_to, to,
4452 cc, bcc, message_id, in_reply_to, references,
4453 subject, comments, keywords, optional_field);
4454 if (field == NULL) {
4455 res = MAILIMF_ERROR_MEMORY;
4456 goto free_field;
4457 }
4458
4459 * result = field;
4460 * index = cur_token;
4461
4462 return MAILIMF_NO_ERROR;
4463
4464 free_field:
4465 if (return_path != NULL)
4466 mailimf_return_free(return_path);
4467 if (resent_date != NULL)
4468 mailimf_orig_date_free(resent_date);
4469 if (resent_from != NULL)
4470 mailimf_from_free(resent_from);
4471 if (resent_sender != NULL)
4472 mailimf_sender_free(resent_sender);
4473 if (resent_to != NULL)
4474 mailimf_to_free(resent_to);
4475 if (resent_cc != NULL)
4476 mailimf_cc_free(resent_cc);
4477 if (resent_bcc != NULL)
4478 mailimf_bcc_free(resent_bcc);
4479 if (resent_msg_id != NULL)
4480 mailimf_message_id_free(resent_msg_id);
4481 if (orig_date != NULL)
4482 mailimf_orig_date_free(orig_date);
4483 if (from != NULL)
4484 mailimf_from_free(from);
4485 if (sender != NULL)
4486 mailimf_sender_free(sender);
4487 if (reply_to != NULL)
4488 mailimf_reply_to_free(reply_to);
4489 if (to != NULL)
4490 mailimf_to_free(to);
4491 if (cc != NULL)
4492 mailimf_cc_free(cc);
4493 if (bcc != NULL)
4494 mailimf_bcc_free(bcc);
4495 if (message_id != NULL)
4496 mailimf_message_id_free(message_id);
4497 if (in_reply_to != NULL)
4498 mailimf_in_reply_to_free(in_reply_to);
4499 if (references != NULL)
4500 mailimf_references_free(references);
4501 if (subject != NULL)
4502 mailimf_subject_free(subject);
4503 if (comments != NULL)
4504 mailimf_comments_free(comments);
4505 if (keywords != NULL)
4506 mailimf_keywords_free(keywords);
4507 if (optional_field != NULL)
4508 mailimf_optional_field_free(optional_field);
4509 err:
4510 return res;
4511}
4512
4513
4514/*
4515fields = *(delivering-info /
4516 orig-date /
4517 from /
4518 sender /
4519 reply-to /
4520 to /
4521 cc /
4522 bcc /
4523 message-id /
4524 in-reply-to /
4525 references /
4526 subject /
4527 comments /
4528 keywords /
4529 optional-field)
4530*/
4531
4532#if 0
4533int
4534mailimf_unparsed_fields_parse(const char * message, size_t length,
4535 size_t * index,
4536 struct mailimf_unparsed_fields ** result)
4537{
4538 size_t cur_token;
4539 clist * list;
4540 struct mailimf_unparsed_fields * fields;
4541 int r;
4542 int res;
4543
4544 cur_token = * index;
4545
4546 list = NULL;
4547
4548 r = mailimf_struct_multiple_parse(message, length, &cur_token,
4549 &list,
4550 (mailimf_struct_parser *)
4551 mailimf_optional_field_parse,
4552 (mailimf_struct_destructor *)
4553 mailimf_optional_field_free);
4554 /*
4555 if ((r = MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
4556 res = r;
4557 goto err;
4558 }
4559 */
4560
4561 switch (r) {
4562 case MAILIMF_NO_ERROR:
4563 /* do nothing */
4564 break;
4565
4566 case MAILIMF_ERROR_PARSE:
4567 list = clist_new();
4568 if (list == NULL) {
4569 res = MAILIMF_ERROR_MEMORY;
4570 goto err;
4571 }
4572 break;
4573
4574 default:
4575 res = r;
4576 goto err;
4577 }
4578
4579 fields = mailimf_unparsed_fields_new(list);
4580 if (fields == NULL) {
4581 res = MAILIMF_ERROR_MEMORY;
4582 goto free;
4583 }
4584
4585 * result = fields;
4586 * index = cur_token;
4587
4588 return MAILIMF_NO_ERROR;
4589
4590 free:
4591 if (list != NULL) {
4592 clist_foreach(list, (clist_func) mailimf_optional_field_free, NULL);
4593 clist_free(list);
4594 }
4595 err:
4596 return res;
4597}
4598#endif
4599
4600int mailimf_fields_parse(const char * message, size_t length,
4601 size_t * index,
4602 struct mailimf_fields ** result)
4603{
4604 size_t cur_token;
4605 clist * list;
4606 struct mailimf_fields * fields;
4607 int r;
4608 int res;
4609
4610 cur_token = * index;
4611
4612 list = NULL;
4613
4614 r = mailimf_struct_multiple_parse(message, length, &cur_token,
4615 &list,
4616 (mailimf_struct_parser *)
4617 mailimf_field_parse,
4618 (mailimf_struct_destructor *)
4619 mailimf_field_free);
4620 /*
4621 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
4622 res = r;
4623 goto err;
4624 }
4625 */
4626
4627 switch (r) {
4628 case MAILIMF_NO_ERROR:
4629 /* do nothing */
4630 break;
4631
4632 case MAILIMF_ERROR_PARSE:
4633 list = clist_new();
4634 if (list == NULL) {
4635 res = MAILIMF_ERROR_MEMORY;
4636 goto err;
4637 }
4638 break;
4639
4640 default:
4641 res = r;
4642 goto err;
4643 }
4644
4645 fields = mailimf_fields_new(list);
4646 if (fields == NULL) {
4647 res = MAILIMF_ERROR_MEMORY;
4648 goto free;
4649 }
4650
4651 * result = fields;
4652 * index = cur_token;
4653
4654 return MAILIMF_NO_ERROR;
4655
4656 free:
4657 if (list != NULL) {
4658 clist_foreach(list, (clist_func) mailimf_field_free, NULL);
4659 clist_free(list);
4660 }
4661 err:
4662 return res;
4663}
4664
4665/*
4666orig-date = "Date:" date-time CRLF
4667*/
4668
4669
4670static int
4671mailimf_orig_date_parse(const char * message, size_t length,
4672 size_t * index, struct mailimf_orig_date ** result)
4673{
4674 struct mailimf_date_time * date_time;
4675 struct mailimf_orig_date * orig_date;
4676 size_t cur_token;
4677 int r;
4678 int res;
4679
4680 cur_token = * index;
4681
4682 r = mailimf_token_case_insensitive_parse(message, length,
4683 &cur_token, "Date:");
4684 if (r != MAILIMF_NO_ERROR) {
4685 res = r;
4686 goto err;
4687 }
4688
4689 r = mailimf_date_time_parse(message, length, &cur_token, &date_time);
4690 if (r != MAILIMF_NO_ERROR) {
4691 res = r;
4692 goto err;
4693 }
4694
4695 r = mailimf_ignore_unstructured_parse(message, length, &cur_token);
4696 if (r != MAILIMF_NO_ERROR) {
4697 res = r;
4698 goto free_date_time;
4699 }
4700
4701 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
4702 if (r != MAILIMF_NO_ERROR) {
4703 res = r;
4704 goto free_date_time;
4705 }
4706
4707 orig_date = mailimf_orig_date_new(date_time);
4708 if (orig_date == NULL) {
4709 res = MAILIMF_ERROR_MEMORY;
4710 goto free_date_time;
4711 }
4712
4713 * result = orig_date;
4714 * index = cur_token;
4715
4716 return MAILIMF_NO_ERROR;
4717
4718 free_date_time:
4719 mailimf_date_time_free(date_time);
4720 err:
4721 return res;
4722}
4723
4724/*
4725from = "From:" mailbox-list CRLF
4726*/
4727
4728static int
4729mailimf_from_parse(const char * message, size_t length,
4730 size_t * index, struct mailimf_from ** result)
4731{
4732 struct mailimf_mailbox_list * mb_list;
4733 struct mailimf_from * from;
4734 size_t cur_token;
4735 int r;
4736 int res;
4737
4738 cur_token = * index;
4739
4740 r = mailimf_token_case_insensitive_parse(message, length,
4741 &cur_token, "From");
4742 if (r != MAILIMF_NO_ERROR) {
4743 res = r;
4744 goto err;
4745 }
4746
4747 r = mailimf_colon_parse(message, length, &cur_token);
4748 if (r != MAILIMF_NO_ERROR) {
4749 res = r;
4750 goto err;
4751 }
4752
4753 r = mailimf_mailbox_list_parse(message, length, &cur_token, &mb_list);
4754
4755 if (r != MAILIMF_NO_ERROR) {
4756 res = r;
4757 goto err;
4758 }
4759
4760 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
4761 if (r != MAILIMF_NO_ERROR) {
4762 res = r;
4763 goto free_mb_list;
4764 }
4765
4766 from = mailimf_from_new(mb_list);
4767 if (from == NULL) {
4768 res = MAILIMF_ERROR_MEMORY;
4769 goto free_mb_list;
4770 }
4771
4772 * result = from;
4773 * index = cur_token;
4774
4775 return MAILIMF_NO_ERROR;
4776
4777 free_mb_list:
4778 mailimf_mailbox_list_free(mb_list);
4779 err:
4780 return res;
4781}
4782
4783/*
4784sender = "Sender:" mailbox CRLF
4785*/
4786
4787static int
4788mailimf_sender_parse(const char * message, size_t length,
4789 size_t * index, struct mailimf_sender ** result)
4790{
4791 struct mailimf_mailbox * mb;
4792 struct mailimf_sender * sender;
4793 size_t cur_token;
4794 int r;
4795 int res;
4796
4797 cur_token = * index;
4798
4799 r = mailimf_token_case_insensitive_parse(message, length,
4800 &cur_token, "Sender");
4801 if (r != MAILIMF_NO_ERROR) {
4802 res = r;
4803 goto err;
4804 }
4805
4806 r = mailimf_colon_parse(message, length, &cur_token);
4807 if (r != MAILIMF_NO_ERROR) {
4808 res = r;
4809 goto err;
4810 }
4811
4812 r = mailimf_mailbox_parse(message, length, &cur_token, &mb);
4813 if (r != MAILIMF_NO_ERROR) {
4814 res = r;
4815 goto err;
4816 }
4817
4818 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
4819 if (r != MAILIMF_NO_ERROR) {
4820 res = r;
4821 goto free_mb;
4822 }
4823
4824 sender = mailimf_sender_new(mb);
4825 if (sender == NULL) {
4826 res = MAILIMF_ERROR_MEMORY;
4827 goto free_mb;
4828 }
4829
4830 * result = sender;
4831 * index = cur_token;
4832
4833 return MAILIMF_NO_ERROR;
4834
4835 free_mb:
4836 mailimf_mailbox_free(mb);
4837 err:
4838 return res;
4839}
4840
4841/*
4842reply-to = "Reply-To:" address-list CRLF
4843*/
4844
4845
4846static int
4847mailimf_reply_to_parse(const char * message, size_t length,
4848 size_t * index, struct mailimf_reply_to ** result)
4849{
4850 struct mailimf_address_list * addr_list;
4851 struct mailimf_reply_to * reply_to;
4852 size_t cur_token;
4853 int r;
4854 int res;
4855
4856 cur_token = * index;
4857
4858 r = mailimf_token_case_insensitive_parse(message, length,
4859 &cur_token, "Reply-To");
4860 if (r != MAILIMF_NO_ERROR) {
4861 res = r;
4862 goto err;
4863 }
4864
4865 r = mailimf_colon_parse(message, length, &cur_token);
4866 if (r != MAILIMF_NO_ERROR) {
4867 res = r;
4868 goto err;
4869 }
4870
4871 r = mailimf_address_list_parse(message, length, &cur_token, &addr_list);
4872 if (r != MAILIMF_NO_ERROR) {
4873 res = r;
4874 goto err;
4875 }
4876
4877 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
4878 if (r != MAILIMF_NO_ERROR) {
4879 res = r;
4880 goto free_addr_list;
4881 }
4882
4883 reply_to = mailimf_reply_to_new(addr_list);
4884 if (reply_to == NULL) {
4885 res = MAILIMF_ERROR_MEMORY;
4886 goto free_addr_list;
4887 }
4888
4889 * result = reply_to;
4890 * index = cur_token;
4891
4892 return MAILIMF_NO_ERROR;
4893
4894 free_addr_list:
4895 mailimf_address_list_free(addr_list);
4896 err:
4897 return res;
4898}
4899
4900/*
4901to = "To:" address-list CRLF
4902*/
4903
4904static int
4905mailimf_to_parse(const char * message, size_t length,
4906 size_t * index, struct mailimf_to ** result)
4907{
4908 struct mailimf_address_list * addr_list;
4909 struct mailimf_to * to;
4910 size_t cur_token;
4911 int r;
4912 int res;
4913
4914 cur_token = * index;
4915
4916 r = mailimf_token_case_insensitive_parse(message, length,
4917 &cur_token, "To");
4918 if (r != MAILIMF_NO_ERROR) {
4919 res = r;
4920 goto err;
4921 }
4922
4923 r = mailimf_colon_parse(message, length, &cur_token);
4924 if (r != MAILIMF_NO_ERROR) {
4925 res = r;
4926 goto err;
4927 }
4928
4929 r = mailimf_address_list_parse(message, length, &cur_token, &addr_list);
4930 if (r != MAILIMF_NO_ERROR) {
4931 res = r;
4932 goto err;
4933 }
4934
4935 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
4936 if (r != MAILIMF_NO_ERROR) {
4937 res = r;
4938 goto free_addr_list;
4939 }
4940
4941 to = mailimf_to_new(addr_list);
4942 if (to == NULL) {
4943 res = MAILIMF_ERROR_MEMORY;
4944 goto free_addr_list;
4945 }
4946
4947 * result = to;
4948 * index = cur_token;
4949
4950 return MAILIMF_NO_ERROR;
4951
4952 free_addr_list:
4953 mailimf_address_list_free(addr_list);
4954 err:
4955 return res;
4956}
4957
4958/*
4959cc = "Cc:" address-list CRLF
4960*/
4961
4962
4963static int
4964mailimf_cc_parse(const char * message, size_t length,
4965 size_t * index, struct mailimf_cc ** result)
4966{
4967 struct mailimf_address_list * addr_list;
4968 struct mailimf_cc * cc;
4969 size_t cur_token;
4970 int r;
4971 int res;
4972
4973 cur_token = * index;
4974
4975 r = mailimf_token_case_insensitive_parse(message, length,
4976 &cur_token, "Cc");
4977 if (r != MAILIMF_NO_ERROR) {
4978 res = r;
4979 goto err;
4980 }
4981
4982 r = mailimf_colon_parse(message, length, &cur_token);
4983 if (r != MAILIMF_NO_ERROR) {
4984 res = r;
4985 goto err;
4986 }
4987
4988 r = mailimf_address_list_parse(message, length, &cur_token, &addr_list);
4989 if (r != MAILIMF_NO_ERROR) {
4990 res = r;
4991 goto err;
4992 }
4993
4994 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
4995 if (r != MAILIMF_NO_ERROR) {
4996 res = r;
4997 goto free_addr_list;
4998 }
4999
5000 cc = mailimf_cc_new(addr_list);
5001 if (cc == NULL) {
5002 res = MAILIMF_ERROR_MEMORY;
5003 goto free_addr_list;
5004 }
5005
5006 * result = cc;
5007 * index = cur_token;
5008
5009 return MAILIMF_NO_ERROR;
5010
5011 free_addr_list:
5012 mailimf_address_list_free(addr_list);
5013 err:
5014 return res;
5015}
5016
5017/*
5018bcc = "Bcc:" (address-list / [CFWS]) CRLF
5019*/
5020
5021
5022static int
5023mailimf_bcc_parse(const char * message, size_t length,
5024 size_t * index, struct mailimf_bcc ** result)
5025{
5026 struct mailimf_address_list * addr_list;
5027 struct mailimf_bcc * bcc;
5028 size_t cur_token;
5029 int r;
5030 int res;
5031
5032 cur_token = * index;
5033 addr_list = NULL;
5034
5035 r = mailimf_token_case_insensitive_parse(message, length,
5036 &cur_token, "Bcc");
5037 if (r != MAILIMF_NO_ERROR) {
5038 res = r;
5039 goto err;
5040 }
5041
5042 r = mailimf_colon_parse(message, length, &cur_token);
5043 if (r != MAILIMF_NO_ERROR) {
5044 res = r;
5045 goto err;
5046 }
5047
5048 r = mailimf_address_list_parse(message, length, &cur_token, &addr_list);
5049 switch (r) {
5050 case MAILIMF_NO_ERROR:
5051 /* do nothing */
5052 break;
5053 case MAILIMF_ERROR_PARSE:
5054 r = mailimf_cfws_parse(message, length, &cur_token);
5055 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
5056 res = r;
5057 goto err;
5058 }
5059 break;
5060 default:
5061 res = r;
5062 goto err;
5063 }
5064
5065 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
5066 if (r != MAILIMF_NO_ERROR) {
5067 res = r;
5068 goto free_addr_list;
5069 }
5070
5071 bcc = mailimf_bcc_new(addr_list);
5072 if (bcc == NULL) {
5073 res = MAILIMF_ERROR_MEMORY;
5074 goto free_addr_list;
5075 }
5076
5077 * result = bcc;
5078 * index = cur_token;
5079
5080 return MAILIMF_NO_ERROR;
5081
5082 free_addr_list:
5083 mailimf_address_list_free(addr_list);
5084 err:
5085 return res;
5086}
5087
5088/*
5089message-id = "Message-ID:" msg-id CRLF
5090*/
5091
5092static int mailimf_message_id_parse(const char * message, size_t length,
5093 size_t * index,
5094 struct mailimf_message_id ** result)
5095{
5096 char * value;
5097 size_t cur_token;
5098 struct mailimf_message_id * message_id;
5099 int r;
5100 int res;
5101
5102 cur_token = * index;
5103
5104 r = mailimf_token_case_insensitive_parse(message, length,
5105 &cur_token, "Message-ID");
5106 if (r != MAILIMF_NO_ERROR) {
5107 res = r;
5108 goto err;
5109 }
5110
5111 r = mailimf_colon_parse(message, length, &cur_token);
5112 if (r != MAILIMF_NO_ERROR) {
5113 res = r;
5114 goto err;
5115 }
5116
5117 r = mailimf_msg_id_parse(message, length, &cur_token, &value);
5118 if (r != MAILIMF_NO_ERROR) {
5119 res = r;
5120 goto err;
5121 }
5122
5123 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
5124 if (r != MAILIMF_NO_ERROR) {
5125 res = r;
5126 goto free_value;
5127 }
5128
5129 message_id = mailimf_message_id_new(value);
5130 if (message_id == NULL) {
5131 res = MAILIMF_ERROR_MEMORY;
5132 goto free_value;
5133 }
5134
5135 * result = message_id;
5136 * index = cur_token;
5137
5138 return MAILIMF_NO_ERROR;
5139
5140 free_value:
5141 mailimf_msg_id_free(value);
5142 err:
5143 return res;
5144}
5145
5146/*
5147in-reply-to = "In-Reply-To:" 1*msg-id CRLF
5148*/
5149
5150int mailimf_msg_id_list_parse(const char * message, size_t length,
5151 size_t * index, clist ** result)
5152{
5153 return mailimf_struct_multiple_parse(message, length, index,
5154 result,
5155 (mailimf_struct_parser *)
5156 mailimf_unstrict_msg_id_parse,
5157 (mailimf_struct_destructor *)
5158 mailimf_msg_id_free);
5159}
5160
5161static int mailimf_in_reply_to_parse(const char * message, size_t length,
5162 size_t * index,
5163 struct mailimf_in_reply_to ** result)
5164{
5165 struct mailimf_in_reply_to * in_reply_to;
5166 size_t cur_token;
5167 clist * msg_id_list;
5168 int res;
5169 int r;
5170
5171 cur_token = * index;
5172
5173 r = mailimf_token_case_insensitive_parse(message, length,
5174 &cur_token, "In-Reply-To");
5175 if (r != MAILIMF_NO_ERROR) {
5176 res = r;
5177 goto err;
5178 }
5179
5180 r = mailimf_colon_parse(message, length, &cur_token);
5181 if (r != MAILIMF_NO_ERROR) {
5182 res = r;
5183 goto err;
5184 }
5185
5186 r = mailimf_msg_id_list_parse(message, length, &cur_token, &msg_id_list);
5187 if (r != MAILIMF_NO_ERROR) {
5188 res = r;
5189 goto err;
5190 }
5191
5192 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
5193 if (r != MAILIMF_NO_ERROR) {
5194 res = r;
5195 goto free_list;
5196 }
5197
5198 in_reply_to = mailimf_in_reply_to_new(msg_id_list);
5199 if (in_reply_to == NULL) {
5200 res = MAILIMF_ERROR_MEMORY;
5201 goto free_list;
5202 }
5203
5204 * result = in_reply_to;
5205 * index = cur_token;
5206
5207 return MAILIMF_NO_ERROR;
5208
5209 free_list:
5210 clist_foreach(msg_id_list, (clist_func) mailimf_msg_id_free, NULL);
5211 clist_free(msg_id_list);
5212 err:
5213 return res;
5214}
5215
5216/*
5217references = "References:" 1*msg-id CRLF
5218*/
5219
5220int mailimf_references_parse(const char * message, size_t length,
5221 size_t * index,
5222 struct mailimf_references ** result)
5223{
5224 struct mailimf_references * references;
5225 size_t cur_token;
5226 clist * msg_id_list;
5227 int r;
5228 int res;
5229
5230 cur_token = * index;
5231
5232 r = mailimf_token_case_insensitive_parse(message, length,
5233 &cur_token, "References");
5234 if (r != MAILIMF_NO_ERROR) {
5235 res = r;
5236 goto err;
5237 }
5238
5239 r = mailimf_colon_parse(message, length, &cur_token);
5240 if (r != MAILIMF_NO_ERROR) {
5241 res = r;
5242 goto err;
5243 }
5244
5245 r = mailimf_msg_id_list_parse(message, length, &cur_token, &msg_id_list);
5246 if (r != MAILIMF_NO_ERROR) {
5247 res = r;
5248 goto err;
5249 }
5250
5251 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
5252 if (r != MAILIMF_NO_ERROR) {
5253 res = r;
5254 goto free_list;
5255 }
5256
5257 references = mailimf_references_new(msg_id_list);
5258 if (references == NULL) {
5259 res = MAILIMF_ERROR_MEMORY;
5260 goto free_list;
5261 }
5262
5263 * result = references;
5264 * index = cur_token;
5265
5266 return MAILIMF_NO_ERROR;
5267
5268 free_list:
5269 clist_foreach(msg_id_list, (clist_func) mailimf_msg_id_free, NULL);
5270 clist_free(msg_id_list);
5271 err:
5272 return res;
5273}
5274
5275/*
5276msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS]
5277*/
5278
5279int mailimf_msg_id_parse(const char * message, size_t length,
5280 size_t * index,
5281 char ** result)
5282{
5283 size_t cur_token;
5284#if 0
5285 char * id_left;
5286 char * id_right;
5287#endif
5288 char * msg_id;
5289 int r;
5290 int res;
5291
5292 cur_token = * index;
5293
5294 r = mailimf_cfws_parse(message, length, &cur_token);
5295 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
5296 return r;
5297
5298 r = mailimf_lower_parse(message, length, &cur_token);
5299 if (r != MAILIMF_NO_ERROR) {
5300 res = r;
5301 goto err;
5302 }
5303
5304 r = mailimf_addr_spec_parse(message, length, &cur_token, &msg_id);
5305 if (r != MAILIMF_NO_ERROR) {
5306 res = r;
5307 goto err;
5308 }
5309
5310 r = mailimf_greater_parse(message, length, &cur_token);
5311 if (r != MAILIMF_NO_ERROR) {
5312 free(msg_id);
5313 res = r;
5314 goto err;
5315 }
5316
5317#if 0
5318 r = mailimf_id_left_parse(message, length, &cur_token, &id_left);
5319 if (r != MAILIMF_NO_ERROR) {
5320 res = r;
5321 goto err;
5322 }
5323
5324 r = mailimf_at_sign_parse(message, length, &cur_token);
5325 if (r != MAILIMF_NO_ERROR) {
5326 res = r;
5327 goto free_id_left;
5328 }
5329
5330 r = mailimf_id_right_parse(message, length, &cur_token, &id_right);
5331 if (r != MAILIMF_NO_ERROR) {
5332 res = r;
5333 goto free_id_left;
5334 }
5335
5336 r = mailimf_greater_parse(message, length, &cur_token);
5337 if (r != MAILIMF_NO_ERROR) {
5338 res = r;
5339 goto free_id_right;
5340 }
5341
5342 msg_id = malloc(strlen(id_left) + strlen(id_right) + 2);
5343 if (msg_id == NULL) {
5344 res = MAILIMF_ERROR_MEMORY;
5345 goto free_id_right;
5346 }
5347 strcpy(msg_id, id_left);
5348 strcat(msg_id, "@");
5349 strcat(msg_id, id_right);
5350
5351 mailimf_id_left_free(id_left);
5352 mailimf_id_right_free(id_right);
5353#endif
5354
5355 * result = msg_id;
5356 * index = cur_token;
5357
5358 return MAILIMF_NO_ERROR;
5359
5360#if 0
5361 free_id_right:
5362 mailimf_id_right_free(id_right);
5363 free_id_left:
5364 mailimf_id_left_free(id_left);
5365#endif
5366 /*
5367 free:
5368 mailimf_atom_free(msg_id);
5369 */
5370 err:
5371 return res;
5372}
5373
5374static int mailimf_parse_unwanted_msg_id(const char * message, size_t length,
5375 size_t * index)
5376{
5377 size_t cur_token;
5378 int r;
5379 char * word;
5380 int token_parsed;
5381
5382 cur_token = * index;
5383
5384 token_parsed = TRUE;
5385 while (token_parsed) {
5386 token_parsed = FALSE;
5387 r = mailimf_word_parse(message, length, &cur_token, &word);
5388 if (r == MAILIMF_NO_ERROR) {
5389 mailimf_word_free(word);
5390 token_parsed = TRUE;
5391 }
5392 else if (r == MAILIMF_ERROR_PARSE) {
5393 /* do nothing */
5394 }
5395 else
5396 return r;
5397 r = mailimf_semi_colon_parse(message, length, &cur_token);
5398 if (r == MAILIMF_NO_ERROR)
5399 token_parsed = TRUE;
5400 else if (r == MAILIMF_ERROR_PARSE) {
5401 /* do nothing */
5402 }
5403 else
5404 return r;
5405 r = mailimf_comma_parse(message, length, &cur_token);
5406 if (r == MAILIMF_NO_ERROR)
5407 token_parsed = TRUE;
5408 else if (r == MAILIMF_ERROR_PARSE) {
5409 /* do nothing */
5410 }
5411 else
5412 return r;
5413 r = mailimf_plus_parse(message, length, &cur_token);
5414 if (r == MAILIMF_NO_ERROR)
5415 token_parsed = TRUE;
5416 else if (r == MAILIMF_ERROR_PARSE) {
5417 /* do nothing */
5418 }
5419 else
5420 return r;
5421 r = mailimf_colon_parse(message, length, &cur_token);
5422 if (r == MAILIMF_NO_ERROR)
5423 token_parsed = TRUE;
5424 else if (r == MAILIMF_ERROR_PARSE) {
5425 /* do nothing */
5426 }
5427 else
5428 return r;
5429 r = mailimf_point_parse(message, length, &cur_token);
5430 if (r == MAILIMF_NO_ERROR)
5431 token_parsed = TRUE;
5432 else if (r == MAILIMF_ERROR_PARSE) {
5433 /* do nothing */
5434 }
5435 else
5436 return r;
5437 r = mailimf_at_sign_parse(message, length, &cur_token);
5438 if (r == MAILIMF_NO_ERROR)
5439 token_parsed = TRUE;
5440 else if (r == MAILIMF_ERROR_PARSE) {
5441 /* do nothing */
5442 }
5443 else
5444 return r;
5445 }
5446
5447 return MAILIMF_NO_ERROR;
5448}
5449
5450static int mailimf_unstrict_msg_id_parse(const char * message, size_t length,
5451 size_t * index,
5452 char ** result)
5453{
5454 char * msgid;
5455 size_t cur_token;
5456 int r;
5457
5458 cur_token = * index;
5459
5460 r = mailimf_cfws_parse(message, length, &cur_token);
5461 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
5462 return r;
5463
5464 r = mailimf_parse_unwanted_msg_id(message, length, &cur_token);
5465 if (r != MAILIMF_NO_ERROR)
5466 return r;
5467
5468 r = mailimf_msg_id_parse(message, length, &cur_token, &msgid);
5469 if (r != MAILIMF_NO_ERROR)
5470 return r;
5471
5472 r = mailimf_parse_unwanted_msg_id(message, length, &cur_token);
5473 if (r != MAILIMF_NO_ERROR)
5474 return r;
5475
5476 * result = msgid;
5477 * index = cur_token;
5478
5479 return MAILIMF_NO_ERROR;
5480}
5481
5482/*
5483id-left = dot-atom-text / no-fold-quote / obs-id-left
5484*/
5485
5486#if 0
5487static int mailimf_id_left_parse(const char * message, size_t length,
5488 size_t * index, char ** result)
5489{
5490 int r;
5491
5492 r = mailimf_dot_atom_text_parse(message, length, index, result);
5493 switch (r) {
5494 case MAILIMF_NO_ERROR:
5495 return MAILIMF_NO_ERROR;
5496 case MAILIMF_ERROR_PARSE:
5497 break;
5498 default:
5499 return r;
5500 }
5501
5502 r = mailimf_no_fold_quote_parse(message, length, index, result);
5503 if (r != MAILIMF_NO_ERROR)
5504 return r;
5505
5506 return MAILIMF_NO_ERROR;
5507}
5508#endif
5509
5510/*
5511id-right = dot-atom-text / no-fold-literal / obs-id-right
5512*/
5513
5514#if 0
5515static int mailimf_id_right_parse(const char * message, size_t length,
5516 size_t * index, char ** result)
5517{
5518 int r;
5519
5520 r = mailimf_dot_atom_text_parse(message, length, index, result);
5521 switch (r) {
5522 case MAILIMF_NO_ERROR:
5523 return MAILIMF_NO_ERROR;
5524 case MAILIMF_ERROR_PARSE:
5525 break;
5526 default:
5527 return r;
5528 }
5529
5530 r = mailimf_no_fold_literal_parse(message, length, index, result);
5531 if (r != MAILIMF_NO_ERROR)
5532 return r;
5533
5534 return MAILIMF_NO_ERROR;
5535}
5536#endif
5537
5538/*
5539no-fold-quote = DQUOTE *(qtext / quoted-pair) DQUOTE
5540*/
5541
5542#if 0
5543static int mailimf_no_fold_quote_char_parse(const char * message, size_t length,
5544 size_t * index, char * result)
5545{
5546 char ch;
5547 size_t cur_token;
5548 int r;
5549
5550 cur_token = * index;
5551
5552#if 0
5553 r = mailimf_qtext_parse(message, length, &cur_token, &ch);
5554#endif
5555
5556 if (cur_token >= length)
5557 return MAILIMF_ERROR_PARSE;
5558
5559 if (is_qtext(message[cur_token])) {
5560 ch = message[cur_token];
5561 cur_token ++;
5562 }
5563 else {
5564 r = mailimf_quoted_pair_parse(message, length, &cur_token, &ch);
5565
5566 if (r != MAILIMF_NO_ERROR)
5567 return r;
5568 }
5569
5570 * index = cur_token;
5571 * result = ch;
5572
5573 return MAILIMF_NO_ERROR;
5574}
5575#endif
5576
5577#if 0
5578static int mailimf_no_fold_quote_parse(const char * message, size_t length,
5579 size_t * index, char ** result)
5580{
5581 size_t cur_token;
5582 size_t begin;
5583 char ch;
5584 char * no_fold_quote;
5585 int r;
5586 int res;
5587
5588 begin = cur_token;
5589 r = mailimf_dquote_parse(message, length, &cur_token);
5590 if (r != MAILIMF_NO_ERROR) {
5591 res = r;
5592 goto err;
5593 }
5594
5595 while (1) {
5596 r = mailimf_no_fold_quote_char_parse(message, length, &cur_token, &ch);
5597 if (r == MAILIMF_NO_ERROR) {
5598 /* do nothing */
5599 }
5600 else if (r == MAILIMF_ERROR_PARSE)
5601 break;
5602 else {
5603 res = r;
5604 goto err;
5605 }
5606 }
5607
5608 r = mailimf_dquote_parse(message, length, &cur_token);
5609 if (r != MAILIMF_NO_ERROR) {
5610 res = r;
5611 goto err;
5612 }
5613
5614 /* no_fold_quote = strndup(message + begin, cur_token - begin); */
5615 no_fold_quote = malloc(cur_token - begin + 1);
5616 if (no_fold_quote == NULL) {
5617 res = MAILIMF_ERROR_MEMORY;
5618 goto err;
5619 }
5620 strncpy(no_fold_quote, message + begin, cur_token - begin);
5621 no_fold_quote[cur_token - begin] = '\0';
5622
5623 * result = no_fold_quote;
5624 * index = cur_token;
5625
5626 return MAILIMF_NO_ERROR;
5627
5628 err:
5629 return res;
5630}
5631#endif
5632
5633/*
5634no-fold-literal = "[" *(dtext / quoted-pair) "]"
5635*/
5636
5637#if 0
5638static inline int
5639mailimf_no_fold_literal_char_parse(const char * message, size_t length,
5640 size_t * index, char * result)
5641{
5642 char ch;
5643 size_t cur_token;
5644 int r;
5645
5646 cur_token = * index;
5647
5648#if 0
5649 r = mailimf_dtext_parse(message, length, &cur_token, &ch);
5650#endif
5651 if (cur_token >= length)
5652 return MAILIMF_ERROR_PARSE;
5653
5654 if (is_dtext(message[cur_token])) {
5655 ch = message[cur_token];
5656 cur_token ++;
5657 }
5658 else {
5659 r = mailimf_quoted_pair_parse(message, length, &cur_token, &ch);
5660
5661 if (r != MAILIMF_NO_ERROR)
5662 return r;
5663 }
5664
5665 * index = cur_token;
5666 * result = ch;
5667
5668 return MAILIMF_NO_ERROR;
5669}
5670#endif
5671
5672#if 0
5673static int mailimf_no_fold_literal_parse(const char * message, size_t length,
5674 size_t * index, char ** result)
5675{
5676 size_t cur_token;
5677 size_t begin;
5678 char ch;
5679 char * no_fold_literal;
5680 int r;
5681 int res;
5682
5683 begin = cur_token;
5684 r = mailimf_obracket_parse(message, length, &cur_token);
5685 if (r != MAILIMF_NO_ERROR) {
5686 res = r;
5687 goto err;
5688 }
5689
5690 while (1) {
5691 r = mailimf_no_fold_literal_char_parse(message, length,
5692 &cur_token, &ch);
5693 if (r == MAILIMF_NO_ERROR) {
5694 /* do nothing */
5695 }
5696 else if (r == MAILIMF_ERROR_PARSE)
5697 break;
5698 else {
5699 res = r;
5700 goto err;
5701 }
5702 }
5703
5704 r = mailimf_cbracket_parse(message, length, &cur_token);
5705 if (r != MAILIMF_NO_ERROR) {
5706 res = r;
5707 goto err;
5708 }
5709
5710 /*
5711 no_fold_literal = strndup(message + begin, cur_token - begin);
5712 */
5713 no_fold_literal = malloc(cur_token - begin + 1);
5714 if (no_fold_literal == NULL) {
5715 res = MAILIMF_NO_ERROR;
5716 goto err;
5717 }
5718 strncpy(no_fold_literal, message + begin, cur_token - begin);
5719 no_fold_literal[cur_token - begin] = '\0';
5720
5721 * result = no_fold_literal;
5722 * index = cur_token;
5723
5724 return MAILIMF_NO_ERROR;
5725
5726 err:
5727 return res;
5728}
5729#endif
5730
5731/*
5732subject = "Subject:" unstructured CRLF
5733*/
5734
5735static int mailimf_subject_parse(const char * message, size_t length,
5736 size_t * index,
5737 struct mailimf_subject ** result)
5738{
5739 struct mailimf_subject * subject;
5740 char * value;
5741 size_t cur_token;
5742 int r;
5743 int res;
5744
5745 cur_token = * index;
5746
5747 r = mailimf_token_case_insensitive_parse(message, length,
5748 &cur_token, "Subject");
5749 if (r != MAILIMF_NO_ERROR) {
5750 res = r;
5751 goto err;
5752 }
5753
5754 r = mailimf_colon_parse(message, length, &cur_token);
5755 if (r != MAILIMF_NO_ERROR) {
5756 res = r;
5757 goto err;
5758 }
5759
5760 r = mailimf_unstructured_parse(message, length, &cur_token, &value);
5761 if (r != MAILIMF_NO_ERROR) {
5762 res = r;
5763 goto err;
5764 }
5765
5766 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
5767 if (r != MAILIMF_NO_ERROR) {
5768 res = r;
5769 goto free_value;
5770 }
5771
5772 subject = mailimf_subject_new(value);
5773 if (subject == NULL) {
5774 res = MAILIMF_ERROR_MEMORY;
5775 goto free_value;
5776 }
5777
5778 * result = subject;
5779 * index = cur_token;
5780
5781 return MAILIMF_NO_ERROR;
5782
5783 free_value:
5784 mailimf_unstructured_free(value);
5785 err:
5786 return res;
5787}
5788
5789/*
5790comments = "Comments:" unstructured CRLF
5791*/
5792
5793static int mailimf_comments_parse(const char * message, size_t length,
5794 size_t * index,
5795 struct mailimf_comments ** result)
5796{
5797 struct mailimf_comments * comments;
5798 char * value;
5799 size_t cur_token;
5800 int r;
5801 int res;
5802
5803 cur_token = * index;
5804
5805 r = mailimf_token_case_insensitive_parse(message, length,
5806 &cur_token, "Comments");
5807 if (r != MAILIMF_NO_ERROR) {
5808 res = r;
5809 goto err;
5810 }
5811
5812 r = mailimf_colon_parse(message, length, &cur_token);
5813 if (r != MAILIMF_NO_ERROR) {
5814 res = r;
5815 goto err;
5816 }
5817
5818 r = mailimf_unstructured_parse(message, length, &cur_token, &value);
5819 if (r != MAILIMF_NO_ERROR) {
5820 res = r;
5821 goto err;
5822 }
5823
5824 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
5825 if (r != MAILIMF_NO_ERROR) {
5826 res = r;
5827 goto free_value;
5828 }
5829
5830 comments = mailimf_comments_new(value);
5831 if (comments == NULL) {
5832 res = MAILIMF_ERROR_MEMORY;
5833 goto free_value;
5834 }
5835
5836 * result = comments;
5837 * index = cur_token;
5838
5839 return MAILIMF_NO_ERROR;
5840
5841 free_value:
5842 mailimf_unstructured_free(value);
5843 err:
5844 return res;
5845}
5846
5847/*
5848keywords = "Keywords:" phrase *("," phrase) CRLF
5849*/
5850
5851static int mailimf_keywords_parse(const char * message, size_t length,
5852 size_t * index,
5853 struct mailimf_keywords ** result)
5854{
5855 struct mailimf_keywords * keywords;
5856 clist * list;
5857 size_t cur_token;
5858 int r;
5859 int res;
5860
5861 cur_token = * index;
5862
5863 r = mailimf_token_case_insensitive_parse(message, length,
5864 &cur_token, "Keywords");
5865 if (r != MAILIMF_NO_ERROR) {
5866 res = r;
5867 goto err;
5868 }
5869
5870 r = mailimf_colon_parse(message, length, &cur_token);
5871 if (r != MAILIMF_NO_ERROR) {
5872 res = r;
5873 goto err;
5874 }
5875
5876 r = mailimf_struct_list_parse(message, length, &cur_token,
5877 &list, ',',
5878 (mailimf_struct_parser *)
5879 mailimf_phrase_parse,
5880 (mailimf_struct_destructor *)
5881 mailimf_phrase_free);
5882 if (r != MAILIMF_NO_ERROR) {
5883 res = r;
5884 goto err;
5885 }
5886
5887 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
5888 if (r != MAILIMF_NO_ERROR) {
5889 res = r;
5890 goto free_list;
5891 }
5892
5893 keywords = mailimf_keywords_new(list);
5894 if (keywords == NULL) {
5895 res = MAILIMF_ERROR_MEMORY;
5896 goto free_list;
5897 }
5898
5899 * result = keywords;
5900 * index = cur_token;
5901
5902 return MAILIMF_NO_ERROR;
5903
5904 free_list:
5905 clist_foreach(list, (clist_func) mailimf_phrase_free, NULL);
5906 clist_free(list);
5907 err:
5908 return res;
5909}
5910
5911/*
5912resent-date = "Resent-Date:" date-time CRLF
5913*/
5914
5915static int
5916mailimf_resent_date_parse(const char * message, size_t length,
5917 size_t * index, struct mailimf_orig_date ** result)
5918{
5919 struct mailimf_orig_date * orig_date;
5920 struct mailimf_date_time * date_time;
5921 size_t cur_token;
5922 int r;
5923 int res;
5924
5925 cur_token = * index;
5926
5927 r = mailimf_token_case_insensitive_parse(message, length,
5928 &cur_token, "Resent-Date");
5929 if (r != MAILIMF_NO_ERROR) {
5930 res = r;
5931 goto err;
5932 }
5933
5934 r = mailimf_colon_parse(message, length, &cur_token);
5935 if (r != MAILIMF_NO_ERROR) {
5936 res = r;
5937 goto err;
5938 }
5939
5940 r = mailimf_date_time_parse(message, length, &cur_token, &date_time);
5941 if (r != MAILIMF_NO_ERROR) {
5942 res = r;
5943 goto err;
5944 }
5945
5946 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
5947 if (r != MAILIMF_NO_ERROR) {
5948 res = r;
5949 goto free_date_time;
5950 }
5951
5952 orig_date = mailimf_orig_date_new(date_time);
5953 if (orig_date == NULL) {
5954 res = MAILIMF_ERROR_MEMORY;
5955 goto free_date_time;
5956 }
5957
5958 * result = orig_date;
5959 * index = cur_token;
5960
5961 return MAILIMF_NO_ERROR;
5962
5963 free_date_time:
5964 mailimf_date_time_free(date_time);
5965 err:
5966 return res;
5967}
5968
5969/*
5970resent-from = "Resent-From:" mailbox-list CRLF
5971*/
5972
5973static int
5974mailimf_resent_from_parse(const char * message, size_t length,
5975 size_t * index, struct mailimf_from ** result)
5976{
5977 struct mailimf_mailbox_list * mb_list;
5978 struct mailimf_from * from;
5979 size_t cur_token;
5980 int r;
5981 int res;
5982
5983 cur_token = * index;
5984
5985 r = mailimf_token_case_insensitive_parse(message, length,
5986 &cur_token, "Resent-From");
5987 if (r != MAILIMF_NO_ERROR) {
5988 res = r;
5989 goto err;
5990 }
5991
5992 r = mailimf_colon_parse(message, length, &cur_token);
5993 if (r != MAILIMF_NO_ERROR) {
5994 res = r;
5995 goto err;
5996 }
5997
5998 r = mailimf_mailbox_list_parse(message, length, &cur_token, &mb_list);
5999 if (r != MAILIMF_NO_ERROR) {
6000 res = r;
6001 goto err;
6002 }
6003
6004 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
6005 if (r != MAILIMF_NO_ERROR) {
6006 res = r;
6007 goto free_mb_list;
6008 }
6009
6010 from = mailimf_from_new(mb_list);
6011 if (from == NULL) {
6012 res = MAILIMF_ERROR_MEMORY;
6013 goto free_mb_list;
6014 }
6015
6016 * result = from;
6017 * index = cur_token;
6018
6019 return MAILIMF_NO_ERROR;
6020
6021 free_mb_list:
6022 mailimf_mailbox_list_free(mb_list);
6023 err:
6024 return res;
6025}
6026
6027/*
6028resent-sender = "Resent-Sender:" mailbox CRLF
6029*/
6030
6031static int
6032mailimf_resent_sender_parse(const char * message, size_t length,
6033 size_t * index, struct mailimf_sender ** result)
6034{
6035 struct mailimf_mailbox * mb;
6036 struct mailimf_sender * sender;
6037 size_t cur_token;
6038 int r;
6039 int res;
6040
6041 cur_token = length;
6042
6043 r = mailimf_token_case_insensitive_parse(message, length,
6044 &cur_token, "Resent-Sender");
6045 if (r != MAILIMF_NO_ERROR) {
6046 res = r;
6047 goto err;
6048 }
6049
6050 r = mailimf_colon_parse(message, length, &cur_token);
6051 if (r != MAILIMF_NO_ERROR) {
6052 res = r;
6053 goto err;
6054 }
6055
6056 r = mailimf_mailbox_parse(message, length, &cur_token, &mb);
6057 if (r != MAILIMF_NO_ERROR) {
6058 res = r;
6059 goto err;
6060 }
6061
6062 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
6063 if (r != MAILIMF_NO_ERROR) {
6064 res = r;
6065 goto free_mb;
6066 }
6067
6068 sender = mailimf_sender_new(mb);
6069 if (sender == NULL) {
6070 res = MAILIMF_ERROR_MEMORY;
6071 goto free_mb;
6072 }
6073
6074 * result = sender;
6075 * index = cur_token;
6076
6077 return MAILIMF_NO_ERROR;
6078
6079 free_mb:
6080 mailimf_mailbox_free(mb);
6081 err:
6082 return res;
6083}
6084
6085/*
6086resent-to = "Resent-To:" address-list CRLF
6087*/
6088
6089static int
6090mailimf_resent_to_parse(const char * message, size_t length,
6091 size_t * index, struct mailimf_to ** result)
6092{
6093 struct mailimf_address_list * addr_list;
6094 struct mailimf_to * to;
6095 size_t cur_token;
6096 int r;
6097 int res;
6098
6099 cur_token = * index;
6100
6101 r = mailimf_token_case_insensitive_parse(message, length,
6102 &cur_token, "Resent-To");
6103 if (r != MAILIMF_NO_ERROR) {
6104 res = r;
6105 goto err;
6106 }
6107
6108 r = mailimf_colon_parse(message, length, &cur_token);
6109 if (r != MAILIMF_NO_ERROR) {
6110 res = r;
6111 goto err;
6112 }
6113
6114 r = mailimf_address_list_parse(message, length, &cur_token, &addr_list);
6115 if (r != MAILIMF_NO_ERROR) {
6116 res = r;
6117 goto err;
6118 }
6119
6120 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
6121 if (r != MAILIMF_NO_ERROR) {
6122 res = r;
6123 goto free_addr_list;
6124 }
6125
6126 to = mailimf_to_new(addr_list);
6127 if (to == NULL) {
6128 res = MAILIMF_ERROR_MEMORY;
6129 goto free_addr_list;
6130 }
6131
6132 * result = to;
6133 * index = cur_token;
6134
6135 return MAILIMF_NO_ERROR;
6136
6137 free_addr_list:
6138 mailimf_address_list_free(addr_list);
6139 err:
6140 return res;
6141}
6142
6143/*
6144resent-cc = "Resent-Cc:" address-list CRLF
6145*/
6146
6147static int
6148mailimf_resent_cc_parse(const char * message, size_t length,
6149 size_t * index, struct mailimf_cc ** result)
6150{
6151 struct mailimf_address_list * addr_list;
6152 struct mailimf_cc * cc;
6153 size_t cur_token;
6154 int r;
6155 int res;
6156
6157 cur_token = * index;
6158
6159 r = mailimf_token_case_insensitive_parse(message, length,
6160 &cur_token, "Resent-Cc");
6161 if (r != MAILIMF_NO_ERROR) {
6162 res = r;
6163 goto err;
6164 }
6165
6166 r = mailimf_colon_parse(message, length, &cur_token);
6167 if (r != MAILIMF_NO_ERROR) {
6168 res = r;
6169 goto err;
6170 }
6171
6172 r = mailimf_address_list_parse(message, length, &cur_token, &addr_list);
6173 if (r != MAILIMF_NO_ERROR) {
6174 res = r;
6175 goto err;
6176 }
6177
6178 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
6179 if (r != MAILIMF_NO_ERROR) {
6180 res = r;
6181 goto free_addr_list;
6182 }
6183
6184 cc = mailimf_cc_new(addr_list);
6185 if (cc == NULL) {
6186 res = MAILIMF_ERROR_MEMORY;
6187 goto free_addr_list;
6188 }
6189
6190 * result = cc;
6191 * index = cur_token;
6192
6193 return MAILIMF_NO_ERROR;
6194
6195 free_addr_list:
6196 mailimf_address_list_free(addr_list);
6197 err:
6198 return res;
6199}
6200
6201/*
6202resent-bcc = "Resent-Bcc:" (address-list / [CFWS]) CRLF
6203*/
6204
6205static int
6206mailimf_resent_bcc_parse(const char * message, size_t length,
6207 size_t * index, struct mailimf_bcc ** result)
6208{
6209 struct mailimf_address_list * addr_list;
6210 struct mailimf_bcc * bcc;
6211 size_t cur_token;
6212 int r;
6213 int res;
6214
6215 cur_token = * index;
6216 bcc = NULL;
6217
6218 r = mailimf_token_case_insensitive_parse(message, length,
6219 &cur_token, "Resent-Bcc");
6220 if (r != MAILIMF_NO_ERROR) {
6221 res = r;
6222 goto err;
6223 }
6224
6225 r = mailimf_colon_parse(message, length, &cur_token);
6226 if (r != MAILIMF_NO_ERROR) {
6227 res = r;
6228 goto err;
6229 }
6230
6231 r = mailimf_address_list_parse(message, length, &cur_token, &addr_list);
6232 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
6233 res = r;
6234 goto err;
6235 }
6236
6237 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
6238 if (r != MAILIMF_NO_ERROR) {
6239 res = r;
6240 goto free_addr_list;
6241 }
6242
6243 bcc = mailimf_bcc_new(addr_list);
6244 if (bcc == NULL) {
6245 res = MAILIMF_ERROR_MEMORY;
6246 goto free_addr_list;
6247 }
6248
6249 * result = bcc;
6250 * index = cur_token;
6251
6252 return TRUE;
6253
6254 free_addr_list:
6255 mailimf_address_list_free(addr_list);
6256 err:
6257 return res;
6258}
6259
6260/*
6261resent-msg-id = "Resent-Message-ID:" msg-id CRLF
6262*/
6263
6264static int
6265mailimf_resent_msg_id_parse(const char * message, size_t length,
6266 size_t * index,
6267 struct mailimf_message_id ** result)
6268{
6269 char * value;
6270 size_t cur_token;
6271 struct mailimf_message_id * message_id;
6272 int r;
6273 int res;
6274
6275 cur_token = * index;
6276
6277 r = mailimf_token_case_insensitive_parse(message, length,
6278 &cur_token, "Resent-Message-ID");
6279 if (r != MAILIMF_NO_ERROR) {
6280 res = r;
6281 goto err;
6282 }
6283
6284 r = mailimf_colon_parse(message, length, &cur_token);
6285 if (r != MAILIMF_NO_ERROR) {
6286 res = r;
6287 goto err;
6288 }
6289
6290 r = mailimf_msg_id_parse(message, length, &cur_token, &value);
6291 if (r != MAILIMF_NO_ERROR) {
6292 res = r;
6293 goto err;
6294 }
6295
6296 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
6297 if (r != MAILIMF_NO_ERROR) {
6298 res = r;
6299 goto free_value;
6300 }
6301
6302 message_id = mailimf_message_id_new(value);
6303 if (message_id == NULL) {
6304 res = MAILIMF_ERROR_MEMORY;
6305 goto free_value;
6306 }
6307
6308 * result = message_id;
6309 * index = cur_token;
6310
6311 return MAILIMF_NO_ERROR;
6312
6313 free_value:
6314 mailimf_msg_id_free(value);
6315 err:
6316 return res;
6317}
6318
6319/*
6320trace = [return]
6321 1*received
6322*/
6323
6324#if 0
6325static int mailimf_trace_parse(const char * message, size_t length,
6326 size_t * index,
6327 struct mailimf_trace ** result)
6328{
6329 size_t cur_token;
6330 struct mailimf_return * return_path;
6331 clist * received_list;
6332 struct mailimf_trace * trace;
6333 int r;
6334 int res;
6335
6336 cur_token = * index;
6337 return_path = NULL;
6338 received_list = NULL;
6339
6340 r = mailimf_return_parse(message, length, &cur_token, &return_path);
6341 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
6342 res = r;
6343 goto err;
6344 }
6345
6346 r = mailimf_struct_multiple_parse(message, length, &cur_token,
6347 &received_list,
6348 (mailimf_struct_parser *)
6349 mailimf_received_parse,
6350 (mailimf_struct_destructor *)
6351 mailimf_received_free);
6352 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
6353 res = r;
6354 goto err;
6355 }
6356
6357 if ((received_list == NULL) && (return_path == NULL)) {
6358 res = MAILIMF_ERROR_PARSE;
6359 goto free_return;
6360 }
6361
6362 trace = mailimf_trace_new(return_path, received_list);
6363 if (trace == NULL) {
6364 res = MAILIMF_ERROR_MEMORY;
6365 goto free_list;
6366 }
6367
6368 * result = trace;
6369 * index = cur_token;
6370
6371 return MAILIMF_NO_ERROR;
6372
6373 free_list:
6374 clist_foreach(received_list, (clist_func) mailimf_received_free, NULL);
6375 clist_free(received_list);
6376 free_return:
6377 if (return_path != NULL)
6378 mailimf_return_free(return_path);
6379 err:
6380 return res;
6381}
6382#endif
6383
6384/*
6385return = "Return-Path:" path CRLF
6386*/
6387
6388static int mailimf_return_parse(const char * message, size_t length,
6389 size_t * index,
6390 struct mailimf_return ** result)
6391{
6392 struct mailimf_path * path;
6393 struct mailimf_return * return_path;
6394 size_t cur_token;
6395 int r;
6396 int res;
6397
6398 cur_token = * index;
6399
6400 r = mailimf_token_case_insensitive_parse(message, length,
6401 &cur_token, "Return-Path");
6402 if (r != MAILIMF_NO_ERROR) {
6403 res = r;
6404 goto err;
6405 }
6406
6407 r = mailimf_colon_parse(message, length, &cur_token);
6408 if (r != MAILIMF_NO_ERROR) {
6409 res = r;
6410 goto err;
6411 }
6412
6413 r = mailimf_path_parse(message, length, &cur_token, &path);
6414 if ( r!= MAILIMF_NO_ERROR) {
6415 res = r;
6416 goto err;
6417 }
6418
6419 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
6420 if (r != MAILIMF_NO_ERROR) {
6421 res = r;
6422 goto free_path;
6423 }
6424
6425 return_path = mailimf_return_new(path);
6426 if (return_path == NULL) {
6427 res = MAILIMF_ERROR_MEMORY;
6428 goto free_path;
6429 }
6430
6431 * result = return_path;
6432 * index = cur_token;
6433
6434 return MAILIMF_NO_ERROR;
6435
6436 free_path:
6437 mailimf_path_free(path);
6438 err:
6439 return res;
6440}
6441
6442/*
6443path = ([CFWS] "<" ([CFWS] / addr-spec) ">" [CFWS]) /
6444 obs-path
6445*/
6446
6447static int mailimf_path_parse(const char * message, size_t length,
6448 size_t * index, struct mailimf_path ** result)
6449{
6450 size_t cur_token;
6451 char * addr_spec;
6452 struct mailimf_path * path;
6453 int res;
6454 int r;
6455
6456 cur_token = * index;
6457 addr_spec = NULL;
6458
6459 r = mailimf_cfws_parse(message, length, &cur_token);
6460 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
6461 res = r;
6462 goto err;
6463 }
6464
6465 r = mailimf_lower_parse(message, length, &cur_token);
6466 if (r != MAILIMF_NO_ERROR) {
6467 res = r;
6468 goto err;
6469 }
6470
6471 r = mailimf_addr_spec_parse(message, length, &cur_token, &addr_spec);
6472 switch (r) {
6473 case MAILIMF_NO_ERROR:
6474 break;
6475 case MAILIMF_ERROR_PARSE:
6476 r = mailimf_cfws_parse(message, length, &cur_token);
6477 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
6478 res = r;
6479 goto err;
6480 }
6481 break;
6482 default:
6483 return r;
6484 }
6485
6486 r = mailimf_greater_parse(message, length, &cur_token);
6487 if (r != MAILIMF_NO_ERROR) {
6488 res = r;
6489 goto err;
6490 }
6491
6492 path = mailimf_path_new(addr_spec);
6493 if (path == NULL) {
6494 res = MAILIMF_ERROR_MEMORY;
6495 goto free_addr_spec;
6496 }
6497
6498 * index = cur_token;
6499 * result = path;
6500
6501 return MAILIMF_NO_ERROR;
6502
6503 free_addr_spec:
6504 if (addr_spec == NULL)
6505 mailimf_addr_spec_free(addr_spec);
6506 err:
6507 return res;
6508}
6509
6510/*
6511received = "Received:" name-val-list ";" date-time CRLF
6512*/
6513
6514#if 0
6515static int mailimf_received_parse(const char * message, size_t length,
6516 size_t * index,
6517 struct mailimf_received ** result)
6518{
6519 size_t cur_token;
6520 struct mailimf_received * received;
6521 struct mailimf_name_val_list * name_val_list;
6522 struct mailimf_date_time * date_time;
6523 int r;
6524 int res;
6525
6526 cur_token = * index;
6527
6528 r = mailimf_token_case_insensitive_parse(message, length,
6529 &cur_token, "Received");
6530 if (r != MAILIMF_NO_ERROR) {
6531 res = r;
6532 goto err;
6533 }
6534
6535 r = mailimf_colon_parse(message, length, &cur_token);
6536 if (r != MAILIMF_NO_ERROR) {
6537 res = r;
6538 goto err;
6539 }
6540
6541 r = mailimf_name_val_list_parse(message, length,
6542 &cur_token, &name_val_list);
6543 if (r != MAILIMF_NO_ERROR) {
6544 res = r;
6545 goto err;
6546 }
6547
6548 r = mailimf_semi_colon_parse(message, length, &cur_token);
6549 if (r != MAILIMF_NO_ERROR) {
6550 res = r;
6551 goto free_name_val_list;
6552 }
6553
6554 r = mailimf_date_time_parse(message, length, &cur_token, &date_time);
6555 if (r != MAILIMF_NO_ERROR) {
6556 res = r;
6557 goto free_name_val_list;
6558 }
6559
6560 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
6561 if (r != MAILIMF_NO_ERROR) {
6562 res = r;
6563 goto free_date_time;
6564 }
6565
6566 received = mailimf_received_new(name_val_list, date_time);
6567 if (received == NULL) {
6568 res = MAILIMF_ERROR_MEMORY;
6569 goto free_date_time;
6570 }
6571
6572 * index = cur_token;
6573 * result = received;
6574
6575 return MAILIMF_NO_ERROR;
6576
6577 free_date_time:
6578 mailimf_date_time_free(date_time);
6579 free_name_val_list:
6580 mailimf_name_val_list_free(name_val_list);
6581 err:
6582 return res;
6583}
6584#endif
6585
6586/*
6587name-val-list = [CFWS] [name-val-pair *(CFWS name-val-pair)]
6588*/
6589
6590#if 0
6591static int
6592mailimf_name_val_list_parse(const char * message, size_t length,
6593 size_t * index,
6594 struct mailimf_name_val_list ** result)
6595{
6596 size_t cur_token;
6597 struct mailimf_name_val_pair * pair;
6598 struct mailimf_name_val_list * name_val_list;
6599 clist* list;
6600 int res;
6601 int r;
6602
6603 cur_token = * index;
6604 list = NULL;
6605
6606 r = mailimf_name_val_pair_parse(message, length, &cur_token, &pair);
6607
6608 if (r == MAILIMF_NO_ERROR){
6609 size_t final_token;
6610
6611 list = clist_new();
6612 if (list == NULL) {
6613 mailimf_name_val_pair_free(pair);
6614 res = MAILIMF_ERROR_MEMORY;
6615 goto err;
6616 }
6617
6618 r = clist_append(list, pair);
6619 if (r < 0) {
6620 mailimf_name_val_pair_free(pair);
6621 res = MAILIMF_ERROR_MEMORY;
6622 goto free_list;
6623 }
6624
6625 final_token = cur_token;
6626
6627 while (1) {
6628 r = mailimf_cfws_parse(message, length, &cur_token);
6629 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
6630 res = r;
6631 goto free_list;
6632 }
6633
6634 r = mailimf_name_val_pair_parse(message, length, &cur_token, &pair);
6635 if (r == MAILIMF_NO_ERROR) {
6636 /* do nothing */
6637 }
6638 else if (r == MAILIMF_ERROR_PARSE)
6639 break;
6640 else {
6641 res = r;
6642 goto free_list;
6643 }
6644
6645 r = clist_append(list, pair);
6646 if (r < 0) {
6647 mailimf_name_val_pair_free(pair);
6648 res = MAILIMF_ERROR_MEMORY;
6649 goto free_list;
6650 }
6651
6652 final_token = cur_token;
6653 }
6654 cur_token = final_token;
6655 }
6656
6657 name_val_list = mailimf_name_val_list_new(list);
6658 if (name_val_list == NULL) {
6659 res = MAILIMF_ERROR_MEMORY;
6660 goto free_list;
6661 }
6662
6663 * index = cur_token;
6664 * result = name_val_list;
6665
6666 return MAILIMF_NO_ERROR;
6667
6668 free_list:
6669 if (list != NULL) {
6670 clist_foreach(list, (clist_func) mailimf_name_val_pair_free, NULL);
6671 clist_free(list);
6672 }
6673 err:
6674 return res;
6675}
6676#endif
6677
6678/*
6679name-val-pair = item-name CFWS item-value
6680*/
6681
6682#if 0
6683static int
6684mailimf_name_val_pair_parse(const char * message, size_t length,
6685 size_t * index,
6686 struct mailimf_name_val_pair ** result)
6687{
6688 size_t cur_token;
6689 char * item_name;
6690 struct mailimf_item_value * item_value;
6691 struct mailimf_name_val_pair * name_val_pair;
6692 int r;
6693 int res;
6694
6695 cur_token = * index;
6696
6697 r = mailimf_cfws_parse(message, length, &cur_token);
6698 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
6699 res = r;
6700 goto err;
6701 }
6702
6703 r = mailimf_item_name_parse(message, length, &cur_token, &item_name);
6704 if (r != MAILIMF_NO_ERROR) {
6705 res = r;
6706 goto err;
6707 }
6708
6709 r = mailimf_cfws_parse(message, length, &cur_token);
6710 if (r != MAILIMF_NO_ERROR) {
6711 res = r;
6712 goto free_item_name;
6713 }
6714
6715 r = mailimf_item_value_parse(message, length, &cur_token, &item_value);
6716 if (r != MAILIMF_NO_ERROR) {
6717 res = r;
6718 goto free_item_name;
6719 }
6720
6721 name_val_pair = mailimf_name_val_pair_new(item_name, item_value);
6722 if (name_val_pair == NULL) {
6723 res = MAILIMF_ERROR_MEMORY;
6724 goto free_item_value;
6725 }
6726
6727 * result = name_val_pair;
6728 * index = cur_token;
6729
6730 return MAILIMF_NO_ERROR;
6731
6732 free_item_value:
6733 mailimf_item_value_free(item_value);
6734 free_item_name:
6735 mailimf_item_name_free(item_name);
6736 err:
6737 return res;
6738}
6739#endif
6740
6741/*
6742item-name = ALPHA *(["-"] (ALPHA / DIGIT))
6743*/
6744
6745#if 0
6746static int mailimf_item_name_parse(const char * message, size_t length,
6747 size_t * index, char ** result)
6748{
6749 size_t cur_token;
6750 size_t begin;
6751 char * item_name;
6752 char ch;
6753 int digit;
6754 int r;
6755 int res;
6756
6757 cur_token = * index;
6758
6759 begin = cur_token;
6760
6761 r = mailimf_alpha_parse(message, length, &cur_token, &ch);
6762 if (r != MAILIMF_NO_ERROR) {
6763 res = r;
6764 goto err;
6765 }
6766
6767 while (1) {
6768 int minus_sign;
6769
6770 minus_sign = mailimf_minus_parse(message, length, &cur_token);
6771
6772 r = mailimf_alpha_parse(message, length, &cur_token, &ch);
6773 if (r == MAILIMF_ERROR_PARSE)
6774 r = mailimf_digit_parse(message, length, &cur_token, &digit);
6775
6776 if (r == MAILIMF_NO_ERROR) {
6777 /* do nothing */
6778 }
6779 if (r == MAILIMF_ERROR_PARSE)
6780 break;
6781 else if (r != MAILIMF_NO_ERROR) {
6782 res = r;
6783 goto err;
6784 }
6785 }
6786
6787 item_name = strndup(message + begin, cur_token - begin);
6788 if (item_name == NULL) {
6789 res = MAILIMF_ERROR_MEMORY;
6790 goto err;
6791 }
6792
6793 * index = cur_token;
6794 * result = item_name;
6795
6796 return MAILIMF_NO_ERROR;
6797
6798 err:
6799 return res;
6800}
6801#endif
6802
6803/*
6804item-value = 1*angle-addr / addr-spec /
6805 atom / domain / msg-id
6806*/
6807
6808#if 0
6809static int is_item_value_atext(char ch)
6810{
6811 switch (ch) {
6812 case '\t':
6813 case ' ':
6814 case '\r':
6815 case '\n':
6816 case ';':
6817 return FALSE;
6818 default:
6819 return TRUE;
6820 }
6821}
6822
6823static int mailimf_item_value_atom_parse(const char * message, size_t length,
6824 size_t * index, char ** result)
6825{
6826 char * atom;
6827 size_t cur_token;
6828 int r;
6829
6830 cur_token = * index;
6831
6832 r = mailimf_cfws_parse(message, length, &cur_token);
6833 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
6834 return r;
6835
6836 r = mailimf_custom_string_parse(message, length, &cur_token,
6837 &atom, is_item_value_atext);
6838 if (r != MAILIMF_NO_ERROR)
6839 return r;
6840
6841 r = mailimf_cfws_parse(message, length, &cur_token);
6842 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
6843 return r;
6844
6845 * index = cur_token;
6846 * result = atom;
6847
6848 return MAILIMF_NO_ERROR;
6849}
6850
6851static int mailimf_item_value_parse(const char * message, size_t length,
6852 size_t * index,
6853 struct mailimf_item_value ** result)
6854{
6855 size_t cur_token;
6856 clist * angle_addr_list;
6857 char * addr_spec;
6858 char * atom;
6859 char * domain;
6860 char * msg_id;
6861 int type;
6862 struct mailimf_item_value * item_value;
6863 int r;
6864 int res;
6865
6866 cur_token = * index;
6867
6868 angle_addr_list = NULL;
6869 addr_spec = NULL;
6870 atom = NULL;
6871 domain = NULL;
6872 msg_id = NULL;
6873
6874 r = mailimf_struct_multiple_parse(message, length, &cur_token,
6875 &angle_addr_list,
6876 (mailimf_struct_parser *)
6877 mailimf_angle_addr_parse,
6878 (mailimf_struct_destructor *)
6879 mailimf_angle_addr_free);
6880 if (r == MAILIMF_NO_ERROR)
6881 type = MAILIMF_ITEM_VALUE_ANGLE_ADDR_LIST;
6882
6883 if (r == MAILIMF_ERROR_PARSE) {
6884 r = mailimf_addr_spec_parse(message, length, &cur_token,
6885 &addr_spec);
6886 if (r == MAILIMF_NO_ERROR)
6887 type = MAILIMF_ITEM_VALUE_ADDR_SPEC;
6888 }
6889
6890 if (r == MAILIMF_ERROR_PARSE) {
6891 r = mailimf_msg_id_parse(message, length, &cur_token,
6892 &msg_id);
6893 if (r == MAILIMF_NO_ERROR)
6894 type = MAILIMF_ITEM_VALUE_MSG_ID;
6895 }
6896
6897 /*
6898 else if (mailimf_domain_parse(message, length, &cur_token,
6899 &domain))
6900 type = MAILIMF_ITEM_VALUE_DOMAIN;
6901 */
6902 /*
6903 else if (mailimf_atom_parse(message, length, &cur_token,
6904 &atom))
6905 type = MAILIMF_ITEM_VALUE_ATOM;
6906 */
6907
6908 if (r == MAILIMF_ERROR_PARSE) {
6909 r = mailimf_item_value_atom_parse(message, length, &cur_token,
6910 &atom);
6911 if (r == MAILIMF_NO_ERROR)
6912 type = MAILIMF_ITEM_VALUE_ATOM;
6913 }
6914
6915 if (r != MAILIMF_NO_ERROR) {
6916 res = r;
6917 goto err;
6918 }
6919
6920 item_value = mailimf_item_value_new(type, angle_addr_list, addr_spec,
6921 atom, domain, msg_id);
6922 if (item_value == NULL) {
6923 res = MAILIMF_ERROR_MEMORY;
6924 goto free;
6925 }
6926
6927 * result = item_value;
6928 * index = cur_token;
6929
6930 return MAILIMF_NO_ERROR;
6931
6932 free:
6933 if (angle_addr_list != NULL) {
6934 clist_foreach(angle_addr_list, (clist_func) mailimf_angle_addr_free, NULL);
6935 clist_free(angle_addr_list);
6936 }
6937 if (addr_spec != NULL)
6938 mailimf_addr_spec_free(addr_spec);
6939 if (atom != NULL)
6940 mailimf_atom_free(atom);
6941 if (domain != NULL)
6942 mailimf_domain_free(domain);
6943 if (msg_id != NULL)
6944 mailimf_msg_id_free(msg_id);
6945 err:
6946 return res;
6947}
6948#endif
6949
6950/*
6951optional-field = field-name ":" unstructured CRLF
6952*/
6953
6954static int
6955mailimf_optional_field_parse(const char * message, size_t length,
6956 size_t * index,
6957 struct mailimf_optional_field ** result)
6958{
6959 char * name;
6960 char * value;
6961 struct mailimf_optional_field * optional_field;
6962 size_t cur_token;
6963 int r;
6964 int res;
6965
6966 cur_token = * index;
6967
6968 r = mailimf_field_name_parse(message, length, &cur_token, &name);
6969 if (r != MAILIMF_NO_ERROR) {
6970 res = r;
6971 goto err;
6972 }
6973
6974 r = mailimf_colon_parse(message, length, &cur_token);
6975 if (r != MAILIMF_NO_ERROR) {
6976 res = r;
6977 goto free_name;
6978 }
6979
6980 r = mailimf_unstructured_parse(message, length, &cur_token, &value);
6981 if (r != MAILIMF_NO_ERROR) {
6982 res = r;
6983 goto free_name;
6984 }
6985
6986 r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
6987 if (r != MAILIMF_NO_ERROR) {
6988 res = r;
6989 goto free_value;
6990 }
6991
6992 optional_field = mailimf_optional_field_new(name, value);
6993 if (optional_field == NULL) {
6994 res = MAILIMF_ERROR_MEMORY;
6995 goto free_value;
6996 }
6997
6998 * result = optional_field;
6999 * index = cur_token;
7000
7001 return MAILIMF_NO_ERROR;
7002
7003 free_value:
7004 mailimf_unstructured_free(value);
7005 free_name:
7006 mailimf_field_name_free(name);
7007 err:
7008 return res;
7009}
7010
7011/*
7012field-name = 1*ftext
7013*/
7014
7015static inline int is_ftext(char ch);
7016
7017static int mailimf_field_name_parse(const char * message, size_t length,
7018 size_t * index, char ** result)
7019{
7020 char * field_name;
7021 size_t cur_token;
7022 size_t end;
7023
7024 cur_token = * index;
7025
7026 end = cur_token;
7027 if (end >= length) {
7028 return MAILIMF_ERROR_PARSE;
7029 }
7030
7031 while (is_ftext(message[end])) {
7032 end ++;
7033 if (end >= length)
7034 break;
7035 }
7036 if (end == cur_token) {
7037 return MAILIMF_ERROR_PARSE;
7038 }
7039
7040 /* field_name = strndup(message + cur_token, end - cur_token); */
7041 field_name = malloc(end - cur_token + 1);
7042 if (field_name == NULL) {
7043 return MAILIMF_ERROR_MEMORY;
7044 }
7045 strncpy(field_name, message + cur_token, end - cur_token);
7046 field_name[end - cur_token] = '\0';
7047
7048 cur_token = end;
7049
7050 * index = cur_token;
7051 * result = field_name;
7052
7053 return MAILIMF_NO_ERROR;
7054}
7055
7056/*
7057ftext = %d33-57 / ; Any character except
7058 %d59-126 ; controls, SP, and
7059 ; ":".
7060*/
7061
7062static inline int is_ftext(char ch)
7063{
7064 unsigned char uch = (unsigned char) ch;
7065
7066 if (uch < 33)
7067 return FALSE;
7068
7069 if (uch == 58)
7070 return FALSE;
7071
7072 return TRUE;
7073}
7074
7075/*
7076static int mailimf_ftext_parse(const char * message, size_t length,
7077 size_t * index, gchar * result)
7078{
7079 return mailimf_typed_text_parse(message, length, index, result, is_ftext);
7080}
7081*/
7082
7083
7084
7085
7086static int mailimf_envelope_field_parse(const char * message, size_t length,
7087 size_t * index,
7088 struct mailimf_field ** result)
7089{
7090 size_t cur_token;
7091 int type;
7092 struct mailimf_orig_date * orig_date;
7093 struct mailimf_from * from;
7094 struct mailimf_sender * sender;
7095 struct mailimf_reply_to * reply_to;
7096 struct mailimf_to * to;
7097 struct mailimf_cc * cc;
7098 struct mailimf_bcc * bcc;
7099 struct mailimf_message_id * message_id;
7100 struct mailimf_in_reply_to * in_reply_to;
7101 struct mailimf_references * references;
7102 struct mailimf_subject * subject;
7103 struct mailimf_optional_field * optional_field;
7104 struct mailimf_field * field;
7105 int guessed_type;
7106 int r;
7107 int res;
7108
7109 cur_token = * index;
7110
7111 orig_date = NULL;
7112 from = NULL;
7113 sender = NULL;
7114 reply_to = NULL;
7115 to = NULL;
7116 cc = NULL;
7117 bcc = NULL;
7118 message_id = NULL;
7119 in_reply_to = NULL;
7120 references = NULL;
7121 subject = NULL;
7122 optional_field = NULL;
7123
7124 guessed_type = guess_header_type(message, length, cur_token);
7125 type = MAILIMF_FIELD_NONE;
7126
7127 switch (guessed_type) {
7128 case MAILIMF_FIELD_ORIG_DATE:
7129 r = mailimf_orig_date_parse(message, length, &cur_token,
7130 &orig_date);
7131 if (r == MAILIMF_NO_ERROR)
7132 type = guessed_type;
7133 else if (r == MAILIMF_ERROR_PARSE) {
7134 /* do nothing */
7135 }
7136 else {
7137 res = r;
7138 goto err;
7139 }
7140 break;
7141 case MAILIMF_FIELD_FROM:
7142 r = mailimf_from_parse(message, length, &cur_token,
7143 &from);
7144 if (r == MAILIMF_NO_ERROR)
7145 type = guessed_type;
7146 else if (r == MAILIMF_ERROR_PARSE) {
7147 /* do nothing */
7148 }
7149 else {
7150 res = r;
7151 goto err;
7152 }
7153 break;
7154 case MAILIMF_FIELD_SENDER:
7155 r = mailimf_sender_parse(message, length, &cur_token,
7156 &sender);
7157 if (r == MAILIMF_NO_ERROR)
7158 type = guessed_type;
7159 else if (r == MAILIMF_ERROR_PARSE) {
7160 /* do nothing */
7161 }
7162 else {
7163 res = r;
7164 goto err;
7165 }
7166 break;
7167 case MAILIMF_FIELD_REPLY_TO:
7168 r = mailimf_reply_to_parse(message, length, &cur_token,
7169 &reply_to);
7170 if (r == MAILIMF_NO_ERROR)
7171 type = guessed_type;
7172 else if (r == MAILIMF_ERROR_PARSE) {
7173 /* do nothing */
7174 }
7175 else {
7176 res = r;
7177 goto err;
7178 }
7179 break;
7180 case MAILIMF_FIELD_TO:
7181 r = mailimf_to_parse(message, length, &cur_token,
7182 &to);
7183 if (r == MAILIMF_NO_ERROR)
7184 type = guessed_type;
7185 else if (r == MAILIMF_ERROR_PARSE) {
7186 /* do nothing */
7187 }
7188 else {
7189 res = r;
7190 goto err;
7191 }
7192 break;
7193 case MAILIMF_FIELD_CC:
7194 r = mailimf_cc_parse(message, length, &cur_token,
7195 &cc);
7196 if (r == MAILIMF_NO_ERROR)
7197 type = guessed_type;
7198 else if (r == MAILIMF_ERROR_PARSE) {
7199 /* do nothing */
7200 }
7201 else {
7202 res = r;
7203 goto err;
7204 }
7205 break;
7206 case MAILIMF_FIELD_BCC:
7207 r = mailimf_bcc_parse(message, length, &cur_token,
7208 &bcc);
7209 if (r == MAILIMF_NO_ERROR)
7210 type = guessed_type;
7211 else if (r == MAILIMF_ERROR_PARSE) {
7212 /* do nothing */
7213 }
7214 else {
7215 res = r;
7216 goto err;
7217 }
7218 break;
7219 case MAILIMF_FIELD_MESSAGE_ID:
7220 r = mailimf_message_id_parse(message, length, &cur_token,
7221 &message_id);
7222 if (r == MAILIMF_NO_ERROR)
7223 type = guessed_type;
7224 else if (r == MAILIMF_ERROR_PARSE) {
7225 /* do nothing */
7226 }
7227 else {
7228 res = r;
7229 goto err;
7230 }
7231 break;
7232 case MAILIMF_FIELD_IN_REPLY_TO:
7233 r = mailimf_in_reply_to_parse(message, length, &cur_token,
7234 &in_reply_to);
7235 if (r == MAILIMF_NO_ERROR)
7236 type = guessed_type;
7237 else if (r == MAILIMF_ERROR_PARSE) {
7238 /* do nothing */
7239 }
7240 else {
7241 res = r;
7242 goto err;
7243 }
7244 break;
7245 case MAILIMF_FIELD_REFERENCES:
7246 r = mailimf_references_parse(message, length, &cur_token,
7247 &references);
7248 if (r == MAILIMF_NO_ERROR)
7249 type = guessed_type;
7250 else if (r == MAILIMF_ERROR_PARSE) {
7251 /* do nothing */
7252 }
7253 else {
7254 res = r;
7255 goto err;
7256 }
7257 break;
7258 case MAILIMF_FIELD_SUBJECT:
7259 r = mailimf_subject_parse(message, length, &cur_token,
7260 &subject);
7261 if (r == MAILIMF_NO_ERROR)
7262 type = guessed_type;
7263 else if (r == MAILIMF_ERROR_PARSE) {
7264 /* do nothing */
7265 }
7266 else {
7267 res = r;
7268 goto err;
7269 }
7270 break;
7271 }
7272
7273 if (type == MAILIMF_FIELD_NONE) {
7274 res = MAILIMF_ERROR_PARSE;
7275 goto err;
7276 }
7277
7278 field = mailimf_field_new(type, NULL, NULL, NULL, NULL, NULL,
7279 NULL, NULL, NULL,
7280 orig_date, from, sender, reply_to, to,
7281 cc, bcc, message_id, in_reply_to, references,
7282 subject, NULL, NULL, optional_field);
7283 if (field == NULL) {
7284 res = MAILIMF_ERROR_MEMORY;
7285 goto free_field;
7286 }
7287
7288 * result = field;
7289 * index = cur_token;
7290
7291 return MAILIMF_NO_ERROR;
7292
7293 free_field:
7294 if (orig_date != NULL)
7295 mailimf_orig_date_free(orig_date);
7296 if (from != NULL)
7297 mailimf_from_free(from);
7298 if (sender != NULL)
7299 mailimf_sender_free(sender);
7300 if (reply_to != NULL)
7301 mailimf_reply_to_free(reply_to);
7302 if (to != NULL)
7303 mailimf_to_free(to);
7304 if (cc != NULL)
7305 mailimf_cc_free(cc);
7306 if (bcc != NULL)
7307 mailimf_bcc_free(bcc);
7308 if (message_id != NULL)
7309 mailimf_message_id_free(message_id);
7310 if (in_reply_to != NULL)
7311 mailimf_in_reply_to_free(in_reply_to);
7312 if (references != NULL)
7313 mailimf_references_free(references);
7314 if (subject != NULL)
7315 mailimf_subject_free(subject);
7316 if (optional_field != NULL)
7317 mailimf_optional_field_free(optional_field);
7318 err:
7319 return res;
7320}
7321
7322int mailimf_envelope_fields_parse(const char * message, size_t length,
7323 size_t * index,
7324 struct mailimf_fields ** result)
7325{
7326 size_t cur_token;
7327 clist * list;
7328 struct mailimf_fields * fields;
7329 int r;
7330 int res;
7331
7332 cur_token = * index;
7333
7334 list = clist_new();
7335 if (list == NULL) {
7336 res = MAILIMF_ERROR_MEMORY;
7337 goto err;
7338 }
7339
7340 while (1) {
7341 struct mailimf_field * elt;
7342
7343 r = mailimf_envelope_field_parse(message, length, &cur_token, &elt);
7344 if (r == MAILIMF_NO_ERROR) {
7345 r = clist_append(list, elt);
7346 if (r < 0) {
7347 res = MAILIMF_ERROR_MEMORY;
7348 goto free;
7349 }
7350 }
7351 else if (r == MAILIMF_ERROR_PARSE) {
7352 r = mailimf_ignore_field_parse(message, length, &cur_token);
7353 if (r == MAILIMF_NO_ERROR) {
7354 /* do nothing */
7355 }
7356 else if (r == MAILIMF_ERROR_PARSE) {
7357 break;
7358 }
7359 else {
7360 res = r;
7361 goto free;
7362 }
7363 }
7364 else {
7365 res = r;
7366 goto free;
7367 }
7368 }
7369
7370 fields = mailimf_fields_new(list);
7371 if (fields == NULL) {
7372 res = MAILIMF_ERROR_MEMORY;
7373 goto free;
7374 }
7375
7376 * result = fields;
7377 * index = cur_token;
7378
7379 return MAILIMF_NO_ERROR;
7380
7381 free:
7382 if (list != NULL) {
7383 clist_foreach(list, (clist_func) mailimf_field_free, NULL);
7384 clist_free(list);
7385 }
7386 err:
7387 return res;
7388}
7389
7390
7391static int
7392mailimf_envelope_or_optional_field_parse(const char * message,
7393 size_t length,
7394 size_t * index,
7395 struct mailimf_field ** result)
7396{
7397 int r;
7398 size_t cur_token;
7399 struct mailimf_optional_field * optional_field;
7400 struct mailimf_field * field;
7401
7402 r = mailimf_envelope_field_parse(message, length, index, result);
7403 if (r == MAILIMF_NO_ERROR)
7404 return MAILIMF_NO_ERROR;
7405
7406 cur_token = * index;
7407
7408 r = mailimf_optional_field_parse(message, length, &cur_token,
7409 &optional_field);
7410 if (r != MAILIMF_NO_ERROR)
7411 return r;
7412
7413 field = mailimf_field_new(MAILIMF_FIELD_OPTIONAL_FIELD, NULL,
7414 NULL, NULL, NULL,
7415 NULL, NULL, NULL,
7416 NULL, NULL, NULL,
7417 NULL, NULL, NULL,
7418 NULL, NULL, NULL, NULL, NULL,
7419 NULL, NULL, NULL, optional_field);
7420 if (field == NULL) {
7421 mailimf_optional_field_free(optional_field);
7422 return MAILIMF_ERROR_MEMORY;
7423 }
7424
7425 * result = field;
7426 * index = cur_token;
7427
7428 return MAILIMF_NO_ERROR;
7429}
7430
7431
7432int
7433mailimf_envelope_and_optional_fields_parse(const char * message, size_t length,
7434 size_t * index,
7435 struct mailimf_fields ** result)
7436{
7437 size_t cur_token;
7438 clist * list;
7439 struct mailimf_fields * fields;
7440 int r;
7441 int res;
7442
7443 cur_token = * index;
7444
7445 list = NULL;
7446
7447 r = mailimf_struct_multiple_parse(message, length, &cur_token,
7448 &list,
7449 (mailimf_struct_parser *)
7450 mailimf_envelope_or_optional_field_parse,
7451 (mailimf_struct_destructor *)
7452 mailimf_field_free);
7453 switch (r) {
7454 case MAILIMF_NO_ERROR:
7455 /* do nothing */
7456 break;
7457
7458 case MAILIMF_ERROR_PARSE:
7459 list = clist_new();
7460 if (list == NULL) {
7461 res = MAILIMF_ERROR_MEMORY;
7462 goto err;
7463 }
7464 break;
7465
7466 default:
7467 res = r;
7468 goto err;
7469 }
7470
7471 fields = mailimf_fields_new(list);
7472 if (fields == NULL) {
7473 res = MAILIMF_ERROR_MEMORY;
7474 goto free;
7475 }
7476
7477 * result = fields;
7478 * index = cur_token;
7479
7480 return MAILIMF_NO_ERROR;
7481
7482 free:
7483 if (list != NULL) {
7484 clist_foreach(list, (clist_func) mailimf_field_free, NULL);
7485 clist_free(list);
7486 }
7487 err:
7488 return res;
7489}
7490
7491
7492
7493static int
7494mailimf_only_optional_field_parse(const char * message,
7495 size_t length,
7496 size_t * index,
7497 struct mailimf_field ** result)
7498{
7499 int r;
7500 size_t cur_token;
7501 struct mailimf_optional_field * optional_field;
7502 struct mailimf_field * field;
7503
7504 cur_token = * index;
7505
7506 r = mailimf_optional_field_parse(message, length, &cur_token,
7507 &optional_field);
7508 if (r != MAILIMF_NO_ERROR)
7509 return r;
7510
7511 field = mailimf_field_new(MAILIMF_FIELD_OPTIONAL_FIELD, NULL, NULL, NULL,
7512 NULL, NULL, NULL, NULL, NULL,
7513 NULL, NULL, NULL, NULL, NULL,
7514 NULL, NULL, NULL, NULL, NULL,
7515 NULL, NULL, NULL, optional_field);
7516 if (field == NULL) {
7517 mailimf_optional_field_free(optional_field);
7518 return MAILIMF_ERROR_MEMORY;
7519 }
7520
7521 * result = field;
7522 * index = cur_token;
7523
7524 return MAILIMF_NO_ERROR;
7525}
7526
7527
7528int
7529mailimf_optional_fields_parse(const char * message, size_t length,
7530 size_t * index,
7531 struct mailimf_fields ** result)
7532{
7533 size_t cur_token;
7534 clist * list;
7535 struct mailimf_fields * fields;
7536 int r;
7537 int res;
7538
7539 cur_token = * index;
7540
7541 list = NULL;
7542
7543 r = mailimf_struct_multiple_parse(message, length, &cur_token,
7544 &list,
7545 (mailimf_struct_parser *)
7546 mailimf_only_optional_field_parse,
7547 (mailimf_struct_destructor *)
7548 mailimf_field_free);
7549 switch (r) {
7550 case MAILIMF_NO_ERROR:
7551 /* do nothing */
7552 break;
7553
7554 case MAILIMF_ERROR_PARSE:
7555 list = clist_new();
7556 if (list == NULL) {
7557 res = MAILIMF_ERROR_MEMORY;
7558 goto err;
7559 }
7560 break;
7561
7562 default:
7563 res = r;
7564 goto err;
7565 }
7566
7567 fields = mailimf_fields_new(list);
7568 if (fields == NULL) {
7569 res = MAILIMF_ERROR_MEMORY;
7570 goto free;
7571 }
7572
7573 * result = fields;
7574 * index = cur_token;
7575
7576 return MAILIMF_NO_ERROR;
7577
7578 free:
7579 if (list != NULL) {
7580 clist_foreach(list, (clist_func) mailimf_field_free, NULL);
7581 clist_free(list);
7582 }
7583 err:
7584 return res;
7585}
diff --git a/kmicromail/libetpan/imf/mailimf.h b/kmicromail/libetpan/imf/mailimf.h
new file mode 100644
index 0000000..3248e73
--- a/dev/null
+++ b/kmicromail/libetpan/imf/mailimf.h
@@ -0,0 +1,345 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMF_H
37
38#define MAILIMF_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailimf_types.h>
45#include <libetpan/mailimf_write.h>
46#include <libetpan/mailimf_types_helper.h>
47
48#include <inttypes.h>
49#include <sys/types.h>
50
51/*
52 mailimf_message_parse will parse the given message
53
54 @param message this is a string containing the message content
55 @param length this is the size of the given string
56 @param index this is a pointer to the start of the message in
57 the given string, (* index) is modified to point at the end
58 of the parsed data
59 @param result the result of the parse operation is stored in
60 (* result)
61
62 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
63*/
64
65int mailimf_message_parse(const char * message, size_t length,
66 size_t * index,
67 struct mailimf_message ** result);
68
69/*
70 mailimf_body_parse will parse the given text part of a message
71
72 @param message this is a string containing the message text part
73 @param length this is the size of the given string
74 @param index this is a pointer to the start of the message text part in
75 the given string, (* index) is modified to point at the end
76 of the parsed data
77 @param result the result of the parse operation is stored in
78 (* result)
79
80 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
81*/
82
83int mailimf_body_parse(const char * message, size_t length,
84 size_t * index,
85 struct mailimf_body ** result);
86
87/*
88 mailimf_fields_parse will parse the given header fields
89
90 @param message this is a string containing the header fields
91 @param length this is the size of the given string
92 @param index this is a pointer to the start of the header fields in
93 the given string, (* index) is modified to point at the end
94 of the parsed data
95 @param result the result of the parse operation is stored in
96 (* result)
97
98 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
99*/
100
101int mailimf_fields_parse(const char * message, size_t length,
102 size_t * index,
103 struct mailimf_fields ** result);
104
105/*
106 mailimf_mailbox_list_parse will parse the given mailbox list
107
108 @param message this is a string containing the mailbox list
109 @param length this is the size of the given string
110 @param index this is a pointer to the start of the mailbox list in
111 the given string, (* index) is modified to point at the end
112 of the parsed data
113 @param result the result of the parse operation is stored in
114 (* result)
115
116 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
117*/
118
119int
120mailimf_mailbox_list_parse(const char * message, size_t length,
121 size_t * index,
122 struct mailimf_mailbox_list ** result);
123
124/*
125 mailimf_address_list_parse will parse the given address list
126
127 @param message this is a string containing the address list
128 @param length this is the size of the given string
129 @param index this is a pointer to the start of the address list in
130 the given string, (* index) is modified to point at the end
131 of the parsed data
132 @param result the result of the parse operation is stored in
133 (* result)
134
135 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
136*/
137
138int
139mailimf_address_list_parse(const char * message, size_t length,
140 size_t * index,
141 struct mailimf_address_list ** result);
142
143/*
144 mailimf_address_parse will parse the given address
145
146 @param message this is a string containing the address
147 @param length this is the size of the given string
148 @param index this is a pointer to the start of the address in
149 the given string, (* index) is modified to point at the end
150 of the parsed data
151 @param result the result of the parse operation is stored in
152 (* result)
153
154 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
155*/
156
157int mailimf_address_parse(const char * message, size_t length,
158 size_t * index,
159 struct mailimf_address ** result);
160
161/*
162 mailimf_mailbox_parse will parse the given address
163
164 @param message this is a string containing the mailbox
165 @param length this is the size of the given string
166 @param index this is a pointer to the start of the mailbox in
167 the given string, (* index) is modified to point at the end
168 of the parsed data
169 @param result the result of the parse operation is stored in
170 (* result)
171
172 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
173*/
174
175int mailimf_mailbox_parse(const char * message, size_t length,
176 size_t * index,
177 struct mailimf_mailbox ** result);
178
179/*
180 mailimf_date_time_parse will parse the given RFC 2822 date
181
182 @param message this is a string containing the date
183 @param length this is the size of the given string
184 @param index this is a pointer to the start of the date in
185 the given string, (* index) is modified to point at the end
186 of the parsed data
187 @param result the result of the parse operation is stored in
188 (* result)
189
190 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
191*/
192
193int mailimf_date_time_parse(const char * message, size_t length,
194 size_t * index,
195 struct mailimf_date_time ** result);
196
197/*
198 mailimf_envelope_fields_parse will parse the given fields (Date,
199 From, Sender, Reply-To, To, Cc, Bcc, Message-ID, In-Reply-To,
200 References and Subject)
201
202 @param message this is a string containing the header fields
203 @param length this is the size of the given string
204 @param index this is a pointer to the start of the header fields in
205 the given string, (* index) is modified to point at the end
206 of the parsed data
207 @param result the result of the parse operation is stored in
208 (* result)
209
210 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
211*/
212
213int mailimf_envelope_fields_parse(const char * message, size_t length,
214 size_t * index,
215 struct mailimf_fields ** result);
216
217/*
218 mailimf_ignore_field_parse will skip the given field
219
220 @param message this is a string containing the header field
221 @param length this is the size of the given string
222 @param index this is a pointer to the start of the header field in
223 the given string, (* index) is modified to point at the end
224 of the parsed data
225
226 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
227*/
228
229
230int mailimf_ignore_field_parse(const char * message, size_t length,
231 size_t * index);
232
233/*
234 mailimf_envelope_fields will parse the given fields (Date,
235 From, Sender, Reply-To, To, Cc, Bcc, Message-ID, In-Reply-To,
236 References and Subject), other fields will be added as optional
237 fields.
238
239 @param message this is a string containing the header fields
240 @param length this is the size of the given string
241 @param index this is a pointer to the start of the header fields in
242 the given string, (* index) is modified to point at the end
243 of the parsed data
244 @param result the result of the parse operation is stored in
245 (* result)
246
247 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
248*/
249
250
251int
252mailimf_envelope_and_optional_fields_parse(const char * message, size_t length,
253 size_t * index,
254 struct mailimf_fields ** result);
255
256/*
257 mailimf_envelope_fields will parse the given fields as optional
258 fields.
259
260 @param message this is a string containing the header fields
261 @param length this is the size of the given string
262 @param index this is a pointer to the start of the header fields in
263 the given string, (* index) is modified to point at the end
264 of the parsed data
265 @param result the result of the parse operation is stored in
266 (* result)
267
268 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
269*/
270
271int
272mailimf_optional_fields_parse(const char * message, size_t length,
273 size_t * index,
274 struct mailimf_fields ** result);
275
276
277/* internal use, exported for MIME */
278
279int mailimf_fws_parse(const char * message, size_t length, size_t * index);
280
281int mailimf_cfws_parse(const char * message, size_t length,
282 size_t * index);
283
284int mailimf_char_parse(const char * message, size_t length,
285 size_t * index, char token);
286
287int mailimf_unstrict_char_parse(const char * message, size_t length,
288 size_t * index, char token);
289
290int mailimf_crlf_parse(const char * message, size_t length, size_t * index);
291
292int
293mailimf_custom_string_parse(const char * message, size_t length,
294 size_t * index, char ** result,
295 int (* is_custom_char)(char));
296
297int
298mailimf_token_case_insensitive_len_parse(const char * message, size_t length,
299 size_t * index, char * token,
300 size_t token_length);
301
302#define mailimf_token_case_insensitive_parse(message, length, index, token) \
303 mailimf_token_case_insensitive_len_parse(message, length, index, token, \
304 sizeof(token) - 1)
305
306int mailimf_quoted_string_parse(const char * message, size_t length,
307 size_t * index, char ** result);
308
309int
310mailimf_number_parse(const char * message, size_t length,
311 size_t * index, uint32_t * result);
312
313int mailimf_msg_id_parse(const char * message, size_t length,
314 size_t * index,
315 char ** result);
316
317int mailimf_msg_id_list_parse(const char * message, size_t length,
318 size_t * index, clist ** result);
319
320int mailimf_word_parse(const char * message, size_t length,
321 size_t * index, char ** result);
322
323int mailimf_atom_parse(const char * message, size_t length,
324 size_t * index, char ** result);
325
326int mailimf_fws_atom_parse(const char * message, size_t length,
327 size_t * index, char ** result);
328
329int mailimf_fws_word_parse(const char * message, size_t length,
330 size_t * index, char ** result);
331
332int mailimf_fws_quoted_string_parse(const char * message, size_t length,
333 size_t * index, char ** result);
334
335/* exported for IMAP */
336
337int mailimf_references_parse(const char * message, size_t length,
338 size_t * index,
339 struct mailimf_references ** result);
340
341#ifdef __cplusplus
342}
343#endif
344
345#endif
diff --git a/kmicromail/libetpan/imf/mailimf_types.c b/kmicromail/libetpan/imf/mailimf_types.c
new file mode 100644
index 0000000..fbef8f0
--- a/dev/null
+++ b/kmicromail/libetpan/imf/mailimf_types.c
@@ -0,0 +1,868 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimf_types.h"
37#include "mmapstring.h"
38#include <stdlib.h>
39
40void mailimf_atom_free(char * atom)
41{
42 free(atom);
43}
44
45void mailimf_dot_atom_free(char * dot_atom)
46{
47 free(dot_atom);
48}
49
50void mailimf_dot_atom_text_free(char * dot_atom)
51{
52 free(dot_atom);
53}
54
55void mailimf_quoted_string_free(char * quoted_string)
56{
57 free(quoted_string);
58}
59
60void mailimf_word_free(char * word)
61{
62 free(word);
63}
64
65void mailimf_phrase_free(char * phrase)
66{
67 free(phrase);
68}
69
70void mailimf_unstructured_free(char * unstructured)
71{
72 free(unstructured);
73}
74
75
76struct mailimf_date_time *
77mailimf_date_time_new(int dt_day, int dt_month, int dt_year,
78 int dt_hour, int dt_min, int dt_sec, int dt_zone)
79{
80 struct mailimf_date_time * date_time;
81
82 date_time = malloc(sizeof(* date_time));
83 if (date_time == NULL)
84 return NULL;
85
86 date_time->dt_day = dt_day;
87 date_time->dt_month = dt_month;
88 date_time->dt_year = dt_year;
89 date_time->dt_hour = dt_hour;
90 date_time->dt_min = dt_min;
91 date_time->dt_sec = dt_sec;
92 date_time->dt_zone = dt_zone;
93
94 return date_time;
95}
96
97
98void mailimf_date_time_free(struct mailimf_date_time * date_time)
99{
100 free(date_time);
101}
102
103
104
105
106struct mailimf_address *
107mailimf_address_new(int ad_type, struct mailimf_mailbox * ad_mailbox,
108 struct mailimf_group * ad_group)
109{
110 struct mailimf_address * address;
111
112 address = malloc(sizeof(* address));
113 if (address == NULL)
114 return NULL;
115
116 address->ad_type = ad_type;
117 switch (ad_type) {
118 case MAILIMF_ADDRESS_MAILBOX:
119 address->ad_data.ad_mailbox = ad_mailbox;
120 break;
121 case MAILIMF_ADDRESS_GROUP:
122 address->ad_data.ad_group = ad_group;
123 break;
124 }
125
126 return address;
127}
128
129void mailimf_address_free(struct mailimf_address * address)
130{
131 switch (address->ad_type) {
132 case MAILIMF_ADDRESS_MAILBOX:
133 mailimf_mailbox_free(address->ad_data.ad_mailbox);
134 break;
135 case MAILIMF_ADDRESS_GROUP:
136 mailimf_group_free(address->ad_data.ad_group);
137 }
138 free(address);
139}
140
141struct mailimf_mailbox *
142mailimf_mailbox_new(char * mb_display_name, char * mb_addr_spec)
143{
144 struct mailimf_mailbox * mb;
145
146 mb = malloc(sizeof(* mb));
147 if (mb == NULL)
148 return NULL;
149
150 mb->mb_display_name = mb_display_name;
151 mb->mb_addr_spec = mb_addr_spec;
152
153 return mb;
154}
155
156void mailimf_mailbox_free(struct mailimf_mailbox * mailbox)
157{
158 if (mailbox->mb_display_name != NULL)
159 mailimf_display_name_free(mailbox->mb_display_name);
160 mailimf_addr_spec_free(mailbox->mb_addr_spec);
161 free(mailbox);
162}
163
164
165void mailimf_angle_addr_free(char * angle_addr)
166{
167 free(angle_addr);
168}
169
170
171struct mailimf_group *
172mailimf_group_new(char * grp_display_name,
173 struct mailimf_mailbox_list * grp_mb_list)
174{
175 struct mailimf_group * group;
176
177 group = malloc(sizeof(* group));
178 if (group == NULL)
179 return NULL;
180
181 group->grp_display_name = grp_display_name;
182 group->grp_mb_list = grp_mb_list;
183
184 return group;
185}
186
187void mailimf_group_free(struct mailimf_group * group)
188{
189 if (group->grp_mb_list)
190 mailimf_mailbox_list_free(group->grp_mb_list);
191 mailimf_display_name_free(group->grp_display_name);
192 free(group);
193}
194
195void mailimf_display_name_free(char * display_name)
196{
197 mailimf_phrase_free(display_name);
198}
199
200
201struct mailimf_mailbox_list *
202mailimf_mailbox_list_new(clist * mb_list)
203{
204 struct mailimf_mailbox_list * mbl;
205
206 mbl = malloc(sizeof(* mbl));
207 if (mbl == NULL)
208 return NULL;
209
210 mbl->mb_list = mb_list;
211
212 return mbl;
213}
214
215void mailimf_mailbox_list_free(struct mailimf_mailbox_list * mb_list)
216{
217 clist_foreach(mb_list->mb_list, (clist_func) mailimf_mailbox_free, NULL);
218 clist_free(mb_list->mb_list);
219 free(mb_list);
220}
221
222
223
224struct mailimf_address_list *
225mailimf_address_list_new(clist * ad_list)
226{
227 struct mailimf_address_list * addr_list;
228
229 addr_list = malloc(sizeof(* addr_list));
230 if (addr_list == NULL)
231 return NULL;
232
233 addr_list->ad_list = ad_list;
234
235 return addr_list;
236}
237
238void mailimf_address_list_free(struct mailimf_address_list * addr_list)
239{
240 clist_foreach(addr_list->ad_list, (clist_func) mailimf_address_free, NULL);
241 clist_free(addr_list->ad_list);
242 free(addr_list);
243}
244
245
246void mailimf_addr_spec_free(char * addr_spec)
247{
248 free(addr_spec);
249}
250
251void mailimf_local_part_free(char * local_part)
252{
253 free(local_part);
254}
255
256void mailimf_domain_free(char * domain)
257{
258 free(domain);
259}
260
261void mailimf_domain_literal_free(char * domain_literal)
262{
263 free(domain_literal);
264}
265
266
267
268struct mailimf_message *
269mailimf_message_new(struct mailimf_fields * msg_fields,
270 struct mailimf_body * msg_body)
271{
272 struct mailimf_message * message;
273
274 message = malloc(sizeof(* message));
275 if (message == NULL)
276 return NULL;
277
278 message->msg_fields = msg_fields;
279 message->msg_body = msg_body;
280
281 return message;
282}
283
284void mailimf_message_free(struct mailimf_message * message)
285{
286 mailimf_body_free(message->msg_body);
287 mailimf_fields_free(message->msg_fields);
288 free(message);
289}
290
291
292struct mailimf_body * mailimf_body_new(const char * bd_text, size_t bd_size)
293{
294 struct mailimf_body * body;
295
296 body = malloc(sizeof(* body));
297 if (body == NULL)
298 return NULL;
299 body->bd_text = bd_text;
300 body->bd_size = bd_size;
301
302 return body;
303}
304
305void mailimf_body_free(struct mailimf_body * body)
306{
307 free(body);
308}
309
310
311
312struct mailimf_field *
313mailimf_field_new(int fld_type,
314 struct mailimf_return * fld_return_path,
315 struct mailimf_orig_date * fld_resent_date,
316 struct mailimf_from * fld_resent_from,
317 struct mailimf_sender * fld_resent_sender,
318 struct mailimf_to * fld_resent_to,
319 struct mailimf_cc * fld_resent_cc,
320 struct mailimf_bcc * fld_resent_bcc,
321 struct mailimf_message_id * fld_resent_msg_id,
322 struct mailimf_orig_date * fld_orig_date,
323 struct mailimf_from * fld_from,
324 struct mailimf_sender * fld_sender,
325 struct mailimf_reply_to * fld_reply_to,
326 struct mailimf_to * fld_to,
327 struct mailimf_cc * fld_cc,
328 struct mailimf_bcc * fld_bcc,
329 struct mailimf_message_id * fld_message_id,
330 struct mailimf_in_reply_to * fld_in_reply_to,
331 struct mailimf_references * fld_references,
332 struct mailimf_subject * fld_subject,
333 struct mailimf_comments * fld_comments,
334 struct mailimf_keywords * fld_keywords,
335 struct mailimf_optional_field * fld_optional_field)
336{
337 struct mailimf_field * field;
338
339 field = malloc(sizeof(* field));
340 if (field == NULL)
341 return NULL;
342
343 field->fld_type = fld_type;
344 switch (fld_type) {
345 case MAILIMF_FIELD_RETURN_PATH:
346 field->fld_data.fld_return_path = fld_return_path;
347 break;
348 case MAILIMF_FIELD_RESENT_DATE:
349 field->fld_data.fld_resent_date = fld_resent_date;
350 break;
351 case MAILIMF_FIELD_RESENT_FROM:
352 field->fld_data.fld_resent_from = fld_resent_from;
353 break;
354 case MAILIMF_FIELD_RESENT_SENDER:
355 field->fld_data.fld_resent_sender = fld_resent_sender;
356 break;
357 case MAILIMF_FIELD_RESENT_TO:
358 field->fld_data.fld_resent_to = fld_resent_to;
359 break;
360 case MAILIMF_FIELD_RESENT_CC:
361 field->fld_data.fld_resent_cc = fld_resent_cc;
362 break;
363 case MAILIMF_FIELD_RESENT_BCC:
364 field->fld_data.fld_resent_bcc = fld_resent_bcc;
365 break;
366 case MAILIMF_FIELD_RESENT_MSG_ID:
367 field->fld_data.fld_resent_msg_id = fld_resent_msg_id;
368 break;
369 case MAILIMF_FIELD_ORIG_DATE:
370 field->fld_data.fld_orig_date = fld_orig_date;
371 break;
372 case MAILIMF_FIELD_FROM:
373 field->fld_data.fld_from = fld_from;
374 break;
375 case MAILIMF_FIELD_SENDER:
376 field->fld_data.fld_sender = fld_sender;
377 break;
378 case MAILIMF_FIELD_REPLY_TO:
379 field->fld_data.fld_reply_to = fld_reply_to;
380 break;
381 case MAILIMF_FIELD_TO:
382 field->fld_data.fld_to = fld_to;
383 break;
384 case MAILIMF_FIELD_CC:
385 field->fld_data.fld_cc = fld_cc;
386 break;
387 case MAILIMF_FIELD_BCC:
388 field->fld_data.fld_bcc = fld_bcc;
389 break;
390 case MAILIMF_FIELD_MESSAGE_ID:
391 field->fld_data.fld_message_id = fld_message_id;
392 break;
393 case MAILIMF_FIELD_IN_REPLY_TO:
394 field->fld_data.fld_in_reply_to = fld_in_reply_to;
395 break;
396 case MAILIMF_FIELD_REFERENCES:
397 field->fld_data.fld_references = fld_references;
398 break;
399 case MAILIMF_FIELD_SUBJECT:
400 field->fld_data.fld_subject = fld_subject;
401 break;
402 case MAILIMF_FIELD_COMMENTS:
403 field->fld_data.fld_comments = fld_comments;
404 break;
405 case MAILIMF_FIELD_KEYWORDS:
406 field->fld_data.fld_keywords = fld_keywords;
407 break;
408 case MAILIMF_FIELD_OPTIONAL_FIELD:
409 field->fld_data.fld_optional_field = fld_optional_field;
410 break;
411 }
412
413 return field;
414}
415
416void mailimf_field_free(struct mailimf_field * field)
417{
418 switch (field->fld_type) {
419 case MAILIMF_FIELD_RETURN_PATH:
420 mailimf_return_free(field->fld_data.fld_return_path);
421 break;
422 case MAILIMF_FIELD_RESENT_DATE:
423 mailimf_orig_date_free(field->fld_data.fld_resent_date);
424 break;
425 case MAILIMF_FIELD_RESENT_FROM:
426 mailimf_from_free(field->fld_data.fld_resent_from);
427 break;
428 case MAILIMF_FIELD_RESENT_SENDER:
429 mailimf_sender_free(field->fld_data.fld_resent_sender);
430 break;
431 case MAILIMF_FIELD_RESENT_TO:
432 mailimf_to_free(field->fld_data.fld_resent_to);
433 break;
434 case MAILIMF_FIELD_RESENT_CC:
435 mailimf_cc_free(field->fld_data.fld_resent_cc);
436 break;
437 case MAILIMF_FIELD_RESENT_BCC:
438 mailimf_bcc_free(field->fld_data.fld_resent_bcc);
439 break;
440 case MAILIMF_FIELD_RESENT_MSG_ID:
441 mailimf_message_id_free(field->fld_data.fld_resent_msg_id);
442 break;
443 case MAILIMF_FIELD_ORIG_DATE:
444 mailimf_orig_date_free(field->fld_data.fld_orig_date);
445 break;
446 case MAILIMF_FIELD_FROM:
447 mailimf_from_free(field->fld_data.fld_from);
448 break;
449 case MAILIMF_FIELD_SENDER:
450 mailimf_sender_free(field->fld_data.fld_sender);
451 break;
452 case MAILIMF_FIELD_REPLY_TO:
453 mailimf_reply_to_free(field->fld_data.fld_reply_to);
454 break;
455 case MAILIMF_FIELD_TO:
456 mailimf_to_free(field->fld_data.fld_to);
457 break;
458 case MAILIMF_FIELD_CC:
459 mailimf_cc_free(field->fld_data.fld_cc);
460 break;
461 case MAILIMF_FIELD_BCC:
462 mailimf_bcc_free(field->fld_data.fld_bcc);
463 break;
464 case MAILIMF_FIELD_MESSAGE_ID:
465 mailimf_message_id_free(field->fld_data.fld_message_id);
466 break;
467 case MAILIMF_FIELD_IN_REPLY_TO:
468 mailimf_in_reply_to_free(field->fld_data.fld_in_reply_to);
469 break;
470 case MAILIMF_FIELD_REFERENCES:
471 mailimf_references_free(field->fld_data.fld_references);
472 break;
473 case MAILIMF_FIELD_SUBJECT:
474 mailimf_subject_free(field->fld_data.fld_subject);
475 break;
476 case MAILIMF_FIELD_COMMENTS:
477 mailimf_comments_free(field->fld_data.fld_comments);
478 break;
479 case MAILIMF_FIELD_KEYWORDS:
480 mailimf_keywords_free(field->fld_data.fld_keywords);
481 break;
482 case MAILIMF_FIELD_OPTIONAL_FIELD:
483 mailimf_optional_field_free(field->fld_data.fld_optional_field);
484 break;
485 }
486
487 free(field);
488}
489
490struct mailimf_fields * mailimf_fields_new(clist * fld_list)
491{
492 struct mailimf_fields * fields;
493
494 fields = malloc(sizeof(* fields));
495 if (fields == NULL)
496 return NULL;
497
498 fields->fld_list = fld_list;
499
500 return fields;
501}
502
503void mailimf_fields_free(struct mailimf_fields * fields)
504{
505 if (fields->fld_list != NULL) {
506 clist_foreach(fields->fld_list, (clist_func) mailimf_field_free, NULL);
507 clist_free(fields->fld_list);
508 }
509 free(fields);
510}
511
512
513struct mailimf_orig_date * mailimf_orig_date_new(struct mailimf_date_time *
514 dt_date_time)
515{
516 struct mailimf_orig_date * orig_date;
517
518 orig_date = malloc(sizeof(* orig_date));
519 if (orig_date == NULL)
520 return NULL;
521
522 orig_date->dt_date_time = dt_date_time;
523
524 return orig_date;
525}
526
527void mailimf_orig_date_free(struct mailimf_orig_date * orig_date)
528{
529 if (orig_date->dt_date_time != NULL)
530 mailimf_date_time_free(orig_date->dt_date_time);
531 free(orig_date);
532}
533
534struct mailimf_from *
535mailimf_from_new(struct mailimf_mailbox_list * frm_mb_list)
536{
537 struct mailimf_from * from;
538
539 from = malloc(sizeof(* from));
540 if (from == NULL)
541 return NULL;
542
543 from->frm_mb_list = frm_mb_list;
544
545 return from;
546}
547
548void mailimf_from_free(struct mailimf_from * from)
549{
550 if (from->frm_mb_list != NULL)
551 mailimf_mailbox_list_free(from->frm_mb_list);
552 free(from);
553}
554
555struct mailimf_sender * mailimf_sender_new(struct mailimf_mailbox * snd_mb)
556{
557 struct mailimf_sender * sender;
558
559 sender = malloc(sizeof(* sender));
560 if (sender == NULL)
561 return NULL;
562
563 sender->snd_mb = snd_mb;
564
565 return sender;
566}
567
568void mailimf_sender_free(struct mailimf_sender * sender)
569{
570 if (sender->snd_mb != NULL)
571 mailimf_mailbox_free(sender->snd_mb);
572 free(sender);
573}
574
575struct mailimf_reply_to *
576mailimf_reply_to_new(struct mailimf_address_list * rt_addr_list)
577{
578 struct mailimf_reply_to * reply_to;
579
580 reply_to = malloc(sizeof(* reply_to));
581 if (reply_to == NULL)
582 return NULL;
583
584 reply_to->rt_addr_list = rt_addr_list;
585
586 return reply_to;
587}
588
589void mailimf_reply_to_free(struct mailimf_reply_to * reply_to)
590{
591 if (reply_to->rt_addr_list != NULL)
592 mailimf_address_list_free(reply_to->rt_addr_list);
593 free(reply_to);
594}
595
596struct mailimf_to * mailimf_to_new(struct mailimf_address_list * to_addr_list)
597{
598 struct mailimf_to * to;
599
600 to = malloc(sizeof(* to));
601 if (to == NULL)
602 return NULL;
603
604 to->to_addr_list = to_addr_list;
605
606 return to;
607}
608
609void mailimf_to_free(struct mailimf_to * to)
610{
611 if (to->to_addr_list != NULL)
612 mailimf_address_list_free(to->to_addr_list);
613 free(to);
614}
615
616struct mailimf_cc * mailimf_cc_new(struct mailimf_address_list * cc_addr_list)
617{
618 struct mailimf_cc * cc;
619
620 cc = malloc(sizeof(* cc));
621 if (cc == NULL)
622 return NULL;
623
624 cc->cc_addr_list = cc_addr_list;
625
626 return cc;
627}
628
629void mailimf_cc_free(struct mailimf_cc * cc)
630{
631 if (cc->cc_addr_list != NULL)
632 mailimf_address_list_free(cc->cc_addr_list);
633 free(cc);
634}
635
636struct mailimf_bcc *
637mailimf_bcc_new(struct mailimf_address_list * bcc_addr_list)
638{
639 struct mailimf_bcc * bcc;
640
641 bcc = malloc(sizeof(* bcc));
642 if (bcc == NULL)
643 return NULL;
644
645 bcc->bcc_addr_list = bcc_addr_list;
646
647 return bcc;
648}
649
650void mailimf_bcc_free(struct mailimf_bcc * bcc)
651{
652 if (bcc->bcc_addr_list != NULL)
653 mailimf_address_list_free(bcc->bcc_addr_list);
654 free(bcc);
655}
656
657struct mailimf_message_id * mailimf_message_id_new(char * mid_value)
658{
659 struct mailimf_message_id * message_id;
660
661 message_id = malloc(sizeof(* message_id));
662 if (message_id == NULL)
663 return NULL;
664
665 message_id->mid_value = mid_value;
666
667 return message_id;
668}
669
670void mailimf_message_id_free(struct mailimf_message_id * message_id)
671{
672 if (message_id->mid_value != NULL)
673 mailimf_msg_id_free(message_id->mid_value);
674 free(message_id);
675}
676
677struct mailimf_in_reply_to * mailimf_in_reply_to_new(clist * mid_list)
678{
679 struct mailimf_in_reply_to * in_reply_to;
680
681 in_reply_to = malloc(sizeof(* in_reply_to));
682 if (in_reply_to == NULL)
683 return NULL;
684
685 in_reply_to->mid_list = mid_list;
686
687 return in_reply_to;
688}
689
690void mailimf_in_reply_to_free(struct mailimf_in_reply_to * in_reply_to)
691{
692 clist_foreach(in_reply_to->mid_list,
693 (clist_func) mailimf_msg_id_free, NULL);
694 clist_free(in_reply_to->mid_list);
695 free(in_reply_to);
696}
697
698struct mailimf_references * mailimf_references_new(clist * mid_list)
699{
700 struct mailimf_references * ref;
701
702 ref = malloc(sizeof(* ref));
703 if (ref == NULL)
704 return NULL;
705
706 ref->mid_list = mid_list;
707
708 return ref;
709}
710
711void mailimf_references_free(struct mailimf_references * references)
712{
713 clist_foreach(references->mid_list,
714 (clist_func) mailimf_msg_id_free, NULL);
715 clist_free(references->mid_list);
716 free(references);
717}
718
719void mailimf_msg_id_free(char * msg_id)
720{
721 free(msg_id);
722}
723
724void mailimf_id_left_free(char * id_left)
725{
726 free(id_left);
727}
728
729void mailimf_id_right_free(char * id_right)
730{
731 free(id_right);
732}
733
734void mailimf_no_fold_quote_free(char * nfq)
735{
736 free(nfq);
737}
738
739void mailimf_no_fold_literal_free(char * nfl)
740{
741 free(nfl);
742}
743
744struct mailimf_subject * mailimf_subject_new(char * sbj_value)
745{
746 struct mailimf_subject * subject;
747
748 subject = malloc(sizeof(* subject));
749 if (subject == NULL)
750 return NULL;
751
752 subject->sbj_value = sbj_value;
753
754 return subject;
755}
756
757void mailimf_subject_free(struct mailimf_subject * subject)
758{
759 mailimf_unstructured_free(subject->sbj_value);
760 free(subject);
761}
762
763struct mailimf_comments * mailimf_comments_new(char * cm_value)
764{
765 struct mailimf_comments * comments;
766
767 comments = malloc(sizeof(* comments));
768 if (comments == NULL)
769 return NULL;
770
771 comments->cm_value = cm_value;
772
773 return comments;
774}
775
776void mailimf_comments_free(struct mailimf_comments * comments)
777{
778 mailimf_unstructured_free(comments->cm_value);
779 free(comments);
780}
781
782struct mailimf_keywords * mailimf_keywords_new(clist * kw_list)
783{
784 struct mailimf_keywords * keywords;
785
786 keywords = malloc(sizeof(* keywords));
787 if (keywords == NULL)
788 return NULL;
789
790 keywords->kw_list = kw_list;
791
792 return keywords;
793}
794
795void mailimf_keywords_free(struct mailimf_keywords * keywords)
796{
797 clist_foreach(keywords->kw_list, (clist_func) mailimf_phrase_free, NULL);
798 clist_free(keywords->kw_list);
799 free(keywords);
800}
801
802struct mailimf_return *
803mailimf_return_new(struct mailimf_path * ret_path)
804{
805 struct mailimf_return * return_path;
806
807 return_path = malloc(sizeof(* return_path));
808 if (return_path == NULL)
809 return NULL;
810
811 return_path->ret_path = ret_path;
812
813 return return_path;
814}
815
816void mailimf_return_free(struct mailimf_return * return_path)
817{
818 mailimf_path_free(return_path->ret_path);
819 free(return_path);
820}
821
822
823struct mailimf_path * mailimf_path_new(char * pt_addr_spec)
824{
825 struct mailimf_path * path;
826
827 path = malloc(sizeof(* path));
828 if (path == NULL)
829 return NULL;
830
831 path->pt_addr_spec = pt_addr_spec;
832
833 return path;
834}
835
836void mailimf_path_free(struct mailimf_path * path)
837{
838 if (path->pt_addr_spec != NULL)
839 mailimf_addr_spec_free(path->pt_addr_spec);
840 free(path);
841}
842
843struct mailimf_optional_field *
844mailimf_optional_field_new(char * fld_name, char * fld_value)
845{
846 struct mailimf_optional_field * opt_field;
847
848 opt_field = malloc(sizeof(* opt_field));
849 if (opt_field == NULL)
850 return NULL;
851
852 opt_field->fld_name = fld_name;
853 opt_field->fld_value = fld_value;
854
855 return opt_field;
856}
857
858void mailimf_optional_field_free(struct mailimf_optional_field * opt_field)
859{
860 mailimf_field_name_free(opt_field->fld_name);
861 mailimf_unstructured_free(opt_field->fld_value);
862 free(opt_field);
863}
864
865void mailimf_field_name_free(char * field_name)
866{
867 free(field_name);
868}
diff --git a/kmicromail/libetpan/imf/mailimf_types.h b/kmicromail/libetpan/imf/mailimf_types.h
new file mode 100644
index 0000000..288feb6
--- a/dev/null
+++ b/kmicromail/libetpan/imf/mailimf_types.h
@@ -0,0 +1,793 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32
33/*
34 * $Id$
35 */
36
37#ifndef MAILIMF_TYPES_H
38
39#define MAILIMF_TYPES_H
40
41#ifdef __cplusplus
42extern "C" {
43#endif
44
45#include <libetpan/clist.h>
46#include <sys/types.h>
47
48/*
49 IMPORTANT NOTE:
50
51 All allocation functions will take as argument allocated data
52 and will store these data in the structure they will allocate.
53 Data should be persistant during all the use of the structure
54 and will be freed by the free function of the structure
55
56 allocation functions will return NULL on failure
57*/
58
59/*
60 mailimf_date_time is a date
61
62 - day is the day of month (1 to 31)
63
64 - month (1 to 12)
65
66 - year (4 digits)
67
68 - hour (0 to 23)
69
70 - min (0 to 59)
71
72 - sec (0 to 59)
73
74 - zone (this is the decimal value that we can read, for example:
75 for "-0200", the value is -200)
76*/
77
78struct mailimf_date_time {
79 int dt_day;
80 int dt_month;
81 int dt_year;
82 int dt_hour;
83 int dt_min;
84 int dt_sec;
85 int dt_zone;
86};
87
88struct mailimf_date_time *
89mailimf_date_time_new(int dt_day, int dt_month, int dt_year,
90 int dt_hour, int dt_min, int dt_sec, int dt_zone);
91
92void mailimf_date_time_free(struct mailimf_date_time * date_time);
93
94
95
96/* this is the type of address */
97
98enum {
99 MAILIMF_ADDRESS_ERROR, /* on parse error */
100 MAILIMF_ADDRESS_MAILBOX, /* if this is a mailbox (mailbox@domain) */
101 MAILIMF_ADDRESS_GROUP, /* if this is a group
102 (group_name: address1@domain1,
103 address2@domain2; ) */
104};
105
106/*
107 mailimf_address is an address
108
109 - type can be MAILIMF_ADDRESS_MAILBOX or MAILIMF_ADDRESS_GROUP
110
111 - mailbox is a mailbox if type is MAILIMF_ADDRESS_MAILBOX
112
113 - group is a group if type is MAILIMF_ADDRESS_GROUP
114*/
115
116struct mailimf_address {
117 int ad_type;
118 union {
119 struct mailimf_mailbox * ad_mailbox; /* can be NULL */
120 struct mailimf_group * ad_group; /* can be NULL */
121 } ad_data;
122};
123
124
125struct mailimf_address *
126mailimf_address_new(int ad_type, struct mailimf_mailbox * ad_mailbox,
127 struct mailimf_group * ad_group);
128
129void mailimf_address_free(struct mailimf_address * address);
130
131
132
133/*
134 mailimf_mailbox is a mailbox
135
136 - display_name is the name that will be displayed for this mailbox,
137 for example 'name' in '"name" <mailbox@domain>,
138 should be allocated with malloc()
139
140 - addr_spec is the mailbox, for example 'mailbox@domain'
141 in '"name" <mailbox@domain>, should be allocated with malloc()
142*/
143
144struct mailimf_mailbox {
145 char * mb_display_name; /* can be NULL */
146 char * mb_addr_spec; /* != NULL */
147};
148
149struct mailimf_mailbox *
150mailimf_mailbox_new(char * mb_display_name, char * mb_addr_spec);
151
152void mailimf_mailbox_free(struct mailimf_mailbox * mailbox);
153
154
155
156/*
157 mailimf_group is a group
158
159 - display_name is the name that will be displayed for this group,
160 for example 'group_name' in
161 'group_name: address1@domain1, address2@domain2;', should be allocated
162 with malloc()
163
164 - mb_list is a list of mailboxes
165*/
166
167struct mailimf_group {
168 char * grp_display_name; /* != NULL */
169 struct mailimf_mailbox_list * grp_mb_list; /* can be NULL */
170};
171
172struct mailimf_group *
173mailimf_group_new(char * grp_display_name,
174 struct mailimf_mailbox_list * grp_mb_list);
175
176void mailimf_group_free(struct mailimf_group * group);
177
178
179
180/*
181 mailimf_mailbox_list is a list of mailboxes
182
183 - list is a list of mailboxes
184*/
185
186struct mailimf_mailbox_list {
187 clist * mb_list; /* list of (struct mailimf_mailbox *), != NULL */
188};
189
190struct mailimf_mailbox_list *
191mailimf_mailbox_list_new(clist * mb_list);
192
193void mailimf_mailbox_list_free(struct mailimf_mailbox_list * mb_list);
194
195
196
197/*
198 mailimf_address_list is a list of addresses
199
200 - list is a list of addresses
201*/
202
203struct mailimf_address_list {
204 clist * ad_list; /* list of (struct mailimf_address *), != NULL */
205};
206
207struct mailimf_address_list *
208mailimf_address_list_new(clist * ad_list);
209
210void mailimf_address_list_free(struct mailimf_address_list * addr_list);
211
212
213
214
215
216/*
217 mailimf_body is the text part of a message
218
219 - text is the beginning of the text part, it is a substring
220 of an other string
221
222 - size is the size of the text part
223*/
224
225struct mailimf_body {
226 const char * bd_text; /* != NULL */
227 size_t bd_size;
228};
229
230struct mailimf_body * mailimf_body_new(const char * bd_text, size_t bd_size);
231
232void mailimf_body_free(struct mailimf_body * body);
233
234
235
236
237/*
238 mailimf_message is the content of the message
239
240 - msg_fields is the header fields of the message
241
242 - msg_body is the text part of the message
243*/
244
245struct mailimf_message {
246 struct mailimf_fields * msg_fields; /* != NULL */
247 struct mailimf_body * msg_body; /* != NULL */
248};
249
250struct mailimf_message *
251mailimf_message_new(struct mailimf_fields * msg_fields,
252 struct mailimf_body * msg_body);
253
254void mailimf_message_free(struct mailimf_message * message);
255
256
257
258
259/*
260 mailimf_fields is a list of header fields
261
262 - fld_list is a list of header fields
263*/
264
265struct mailimf_fields {
266 clist * fld_list; /* list of (struct mailimf_field *), != NULL */
267};
268
269struct mailimf_fields * mailimf_fields_new(clist * fld_list);
270
271void mailimf_fields_free(struct mailimf_fields * fields);
272
273
274
275/* this is a type of field */
276
277enum {
278 MAILIMF_FIELD_NONE, /* on parse error */
279 MAILIMF_FIELD_RETURN_PATH, /* Return-Path */
280 MAILIMF_FIELD_RESENT_DATE, /* Resent-Date */
281 MAILIMF_FIELD_RESENT_FROM, /* Resent-From */
282 MAILIMF_FIELD_RESENT_SENDER, /* Resent-Sender */
283 MAILIMF_FIELD_RESENT_TO, /* Resent-To */
284 MAILIMF_FIELD_RESENT_CC, /* Resent-Cc */
285 MAILIMF_FIELD_RESENT_BCC, /* Resent-Bcc */
286 MAILIMF_FIELD_RESENT_MSG_ID, /* Resent-Message-ID */
287 MAILIMF_FIELD_ORIG_DATE, /* Date */
288 MAILIMF_FIELD_FROM, /* From */
289 MAILIMF_FIELD_SENDER, /* Sender */
290 MAILIMF_FIELD_REPLY_TO, /* Reply-To */
291 MAILIMF_FIELD_TO, /* To */
292 MAILIMF_FIELD_CC, /* Cc */
293 MAILIMF_FIELD_BCC, /* Bcc */
294 MAILIMF_FIELD_MESSAGE_ID, /* Message-ID */
295 MAILIMF_FIELD_IN_REPLY_TO, /* In-Reply-To */
296 MAILIMF_FIELD_REFERENCES, /* References */
297 MAILIMF_FIELD_SUBJECT, /* Subject */
298 MAILIMF_FIELD_COMMENTS, /* Comments */
299 MAILIMF_FIELD_KEYWORDS, /* Keywords */
300 MAILIMF_FIELD_OPTIONAL_FIELD, /* other field */
301};
302
303/*
304 mailimf_field is a field
305
306 - fld_type is the type of the field
307
308 - fld_data.fld_return_path is the parsed content of the Return-Path
309 field if type is MAILIMF_FIELD_RETURN_PATH
310
311 - fld_data.fld_resent_date is the parsed content of the Resent-Date field
312 if type is MAILIMF_FIELD_RESENT_DATE
313
314 - fld_data.fld_resent_from is the parsed content of the Resent-From field
315
316 - fld_data.fld_resent_sender is the parsed content of the Resent-Sender field
317
318 - fld_data.fld_resent_to is the parsed content of the Resent-To field
319
320 - fld_data.fld_resent_cc is the parsed content of the Resent-Cc field
321
322 - fld_data.fld_resent_bcc is the parsed content of the Resent-Bcc field
323
324 - fld_data.fld_resent_msg_id is the parsed content of the Resent-Message-ID
325 field
326
327 - fld_data.fld_orig_date is the parsed content of the Date field
328
329 - fld_data.fld_from is the parsed content of the From field
330
331 - fld_data.fld_sender is the parsed content of the Sender field
332
333 - fld_data.fld_reply_to is the parsed content of the Reply-To field
334
335 - fld_data.fld_to is the parsed content of the To field
336
337 - fld_data.fld_cc is the parsed content of the Cc field
338
339 - fld_data.fld_bcc is the parsed content of the Bcc field
340
341 - fld_data.fld_message_id is the parsed content of the Message-ID field
342
343 - fld_data.fld_in_reply_to is the parsed content of the In-Reply-To field
344
345 - fld_data.fld_references is the parsed content of the References field
346
347 - fld_data.fld_subject is the content of the Subject field
348
349 - fld_data.fld_comments is the content of the Comments field
350
351 - fld_data.fld_keywords is the parsed content of the Keywords field
352
353 - fld_data.fld_optional_field is an other field and is not parsed
354*/
355
356#define LIBETPAN_MAILIMF_FIELD_UNION
357
358struct mailimf_field {
359 int fld_type;
360 union {
361 struct mailimf_return * fld_return_path; /* can be NULL */
362 struct mailimf_orig_date * fld_resent_date; /* can be NULL */
363 struct mailimf_from * fld_resent_from; /* can be NULL */
364 struct mailimf_sender * fld_resent_sender; /* can be NULL */
365 struct mailimf_to * fld_resent_to; /* can be NULL */
366 struct mailimf_cc * fld_resent_cc; /* can be NULL */
367 struct mailimf_bcc * fld_resent_bcc; /* can be NULL */
368 struct mailimf_message_id * fld_resent_msg_id; /* can be NULL */
369 struct mailimf_orig_date * fld_orig_date; /* can be NULL */
370 struct mailimf_from * fld_from; /* can be NULL */
371 struct mailimf_sender * fld_sender; /* can be NULL */
372 struct mailimf_reply_to * fld_reply_to; /* can be NULL */
373 struct mailimf_to * fld_to; /* can be NULL */
374 struct mailimf_cc * fld_cc; /* can be NULL */
375 struct mailimf_bcc * fld_bcc; /* can be NULL */
376 struct mailimf_message_id * fld_message_id; /* can be NULL */
377 struct mailimf_in_reply_to * fld_in_reply_to; /* can be NULL */
378 struct mailimf_references * fld_references; /* can be NULL */
379 struct mailimf_subject * fld_subject; /* can be NULL */
380 struct mailimf_comments * fld_comments; /* can be NULL */
381 struct mailimf_keywords * fld_keywords; /* can be NULL */
382 struct mailimf_optional_field * fld_optional_field; /* can be NULL */
383 } fld_data;
384};
385
386struct mailimf_field *
387mailimf_field_new(int fld_type,
388 struct mailimf_return * fld_return_path,
389 struct mailimf_orig_date * fld_resent_date,
390 struct mailimf_from * fld_resent_from,
391 struct mailimf_sender * fld_resent_sender,
392 struct mailimf_to * fld_resent_to,
393 struct mailimf_cc * fld_resent_cc,
394 struct mailimf_bcc * fld_resent_bcc,
395 struct mailimf_message_id * fld_resent_msg_id,
396 struct mailimf_orig_date * fld_orig_date,
397 struct mailimf_from * fld_from,
398 struct mailimf_sender * fld_sender,
399 struct mailimf_reply_to * fld_reply_to,
400 struct mailimf_to * fld_to,
401 struct mailimf_cc * fld_cc,
402 struct mailimf_bcc * fld_bcc,
403 struct mailimf_message_id * fld_message_id,
404 struct mailimf_in_reply_to * fld_in_reply_to,
405 struct mailimf_references * fld_references,
406 struct mailimf_subject * fld_subject,
407 struct mailimf_comments * fld_comments,
408 struct mailimf_keywords * fld_keywords,
409 struct mailimf_optional_field * fld_optional_field);
410
411void mailimf_field_free(struct mailimf_field * field);
412
413
414
415/*
416 mailimf_orig_date is the parsed Date field
417
418 - date_time is the parsed date
419*/
420
421struct mailimf_orig_date {
422 struct mailimf_date_time * dt_date_time; /* != NULL */
423};
424
425struct mailimf_orig_date * mailimf_orig_date_new(struct mailimf_date_time *
426 dt_date_time);
427
428void mailimf_orig_date_free(struct mailimf_orig_date * orig_date);
429
430
431
432
433/*
434 mailimf_from is the parsed From field
435
436 - mb_list is the parsed mailbox list
437*/
438
439struct mailimf_from {
440 struct mailimf_mailbox_list * frm_mb_list; /* != NULL */
441};
442
443struct mailimf_from *
444mailimf_from_new(struct mailimf_mailbox_list * frm_mb_list);
445
446void mailimf_from_free(struct mailimf_from * from);
447
448
449
450/*
451 mailimf_sender is the parsed Sender field
452
453 - snd_mb is the parsed mailbox
454*/
455
456struct mailimf_sender {
457 struct mailimf_mailbox * snd_mb; /* != NULL */
458};
459
460struct mailimf_sender * mailimf_sender_new(struct mailimf_mailbox * snd_mb);
461
462void mailimf_sender_free(struct mailimf_sender * sender);
463
464
465
466
467/*
468 mailimf_reply_to is the parsed Reply-To field
469
470 - rt_addr_list is the parsed address list
471 */
472
473struct mailimf_reply_to {
474 struct mailimf_address_list * rt_addr_list; /* != NULL */
475};
476
477struct mailimf_reply_to *
478mailimf_reply_to_new(struct mailimf_address_list * rt_addr_list);
479
480void mailimf_reply_to_free(struct mailimf_reply_to * reply_to);
481
482
483
484
485/*
486 mailimf_to is the parsed To field
487
488 - to_addr_list is the parsed address list
489*/
490
491struct mailimf_to {
492 struct mailimf_address_list * to_addr_list; /* != NULL */
493};
494
495struct mailimf_to * mailimf_to_new(struct mailimf_address_list * to_addr_list);
496
497void mailimf_to_free(struct mailimf_to * to);
498
499
500
501
502/*
503 mailimf_cc is the parsed Cc field
504
505 - cc_addr_list is the parsed addres list
506*/
507
508struct mailimf_cc {
509 struct mailimf_address_list * cc_addr_list; /* != NULL */
510};
511
512struct mailimf_cc * mailimf_cc_new(struct mailimf_address_list * cc_addr_list);
513
514void mailimf_cc_free(struct mailimf_cc * cc);
515
516
517
518
519/*
520 mailimf_bcc is the parsed Bcc field
521
522 - bcc_addr_list is the parsed addres list
523*/
524
525struct mailimf_bcc {
526 struct mailimf_address_list * bcc_addr_list; /* can be NULL */
527};
528
529struct mailimf_bcc *
530mailimf_bcc_new(struct mailimf_address_list * bcc_addr_list);
531
532void mailimf_bcc_free(struct mailimf_bcc * bcc);
533
534
535
536/*
537 mailimf_message_id is the parsed Message-ID field
538
539 - mid_value is the message identifier
540*/
541
542struct mailimf_message_id {
543 char * mid_value; /* != NULL */
544};
545
546struct mailimf_message_id * mailimf_message_id_new(char * mid_value);
547
548void mailimf_message_id_free(struct mailimf_message_id * message_id);
549
550
551
552
553/*
554 mailimf_in_reply_to is the parsed In-Reply-To field
555
556 - mid_list is the list of message identifers
557*/
558
559struct mailimf_in_reply_to {
560 clist * mid_list; /* list of (char *), != NULL */
561};
562
563struct mailimf_in_reply_to * mailimf_in_reply_to_new(clist * mid_list);
564
565void mailimf_in_reply_to_free(struct mailimf_in_reply_to * in_reply_to);
566
567
568
569/*
570 mailimf_references is the parsed References field
571
572 - msg_id_list is the list of message identifiers
573 */
574
575struct mailimf_references {
576 clist * mid_list; /* list of (char *) */
577 /* != NULL */
578};
579
580struct mailimf_references * mailimf_references_new(clist * mid_list);
581
582void mailimf_references_free(struct mailimf_references * references);
583
584
585
586/*
587 mailimf_subject is the parsed Subject field
588
589 - sbj_value is the value of the field
590*/
591
592struct mailimf_subject {
593 char * sbj_value; /* != NULL */
594};
595
596struct mailimf_subject * mailimf_subject_new(char * sbj_value);
597
598void mailimf_subject_free(struct mailimf_subject * subject);
599
600
601/*
602 mailimf_comments is the parsed Comments field
603
604 - cm_value is the value of the field
605*/
606
607struct mailimf_comments {
608 char * cm_value; /* != NULL */
609};
610
611struct mailimf_comments * mailimf_comments_new(char * cm_value);
612
613void mailimf_comments_free(struct mailimf_comments * comments);
614
615
616/*
617 mailimf_keywords is the parsed Keywords field
618
619 - kw_list is the list of keywords
620*/
621
622struct mailimf_keywords {
623 clist * kw_list; /* list of (char *), != NULL */
624};
625
626struct mailimf_keywords * mailimf_keywords_new(clist * kw_list);
627
628void mailimf_keywords_free(struct mailimf_keywords * keywords);
629
630
631/*
632 mailimf_return is the parsed Return-Path field
633
634 - ret_path is the parsed value of Return-Path
635*/
636
637struct mailimf_return {
638 struct mailimf_path * ret_path; /* != NULL */
639};
640
641struct mailimf_return *
642mailimf_return_new(struct mailimf_path * ret_path);
643
644void mailimf_return_free(struct mailimf_return * return_path);
645
646
647/*
648 mailimf_path is the parsed value of Return-Path
649
650 - pt_addr_spec is a mailbox
651*/
652
653struct mailimf_path {
654 char * pt_addr_spec; /* can be NULL */
655};
656
657struct mailimf_path * mailimf_path_new(char * pt_addr_spec);
658
659void mailimf_path_free(struct mailimf_path * path);
660
661
662/*
663 mailimf_optional_field is a non-parsed field
664
665 - fld_name is the name of the field
666
667 - fld_value is the value of the field
668*/
669
670struct mailimf_optional_field {
671 char * fld_name; /* != NULL */
672 char * fld_value; /* != NULL */
673};
674
675struct mailimf_optional_field *
676mailimf_optional_field_new(char * fld_name, char * fld_value);
677
678void mailimf_optional_field_free(struct mailimf_optional_field * opt_field);
679
680
681/*
682 mailimf_fields is the native structure that IMF module will use,
683 this module will provide an easier structure to use when parsing fields.
684
685 mailimf_single_fields is an easier structure to get parsed fields,
686 rather than iteration over the list of fields
687
688 - fld_orig_date is the parsed "Date" field
689
690 - fld_from is the parsed "From" field
691
692 - fld_sender is the parsed "Sender "field
693
694 - fld_reply_to is the parsed "Reply-To" field
695
696 - fld_to is the parsed "To" field
697
698 - fld_cc is the parsed "Cc" field
699
700 - fld_bcc is the parsed "Bcc" field
701
702 - fld_message_id is the parsed "Message-ID" field
703
704 - fld_in_reply_to is the parsed "In-Reply-To" field
705
706 - fld_references is the parsed "References" field
707
708 - fld_subject is the parsed "Subject" field
709
710 - fld_comments is the parsed "Comments" field
711
712 - fld_keywords is the parsed "Keywords" field
713*/
714
715struct mailimf_single_fields {
716 struct mailimf_orig_date * fld_orig_date; /* can be NULL */
717 struct mailimf_from * fld_from; /* can be NULL */
718 struct mailimf_sender * fld_sender; /* can be NULL */
719 struct mailimf_reply_to * fld_reply_to; /* can be NULL */
720 struct mailimf_to * fld_to; /* can be NULL */
721 struct mailimf_cc * fld_cc; /* can be NULL */
722 struct mailimf_bcc * fld_bcc; /* can be NULL */
723 struct mailimf_message_id * fld_message_id; /* can be NULL */
724 struct mailimf_in_reply_to * fld_in_reply_to; /* can be NULL */
725 struct mailimf_references * fld_references; /* can be NULL */
726 struct mailimf_subject * fld_subject; /* can be NULL */
727 struct mailimf_comments * fld_comments; /* can be NULL */
728 struct mailimf_keywords * fld_keywords; /* can be NULL */
729};
730
731
732
733
734
735
736/* internal use */
737
738void mailimf_atom_free(char * atom);
739
740void mailimf_dot_atom_free(char * dot_atom);
741
742void mailimf_dot_atom_text_free(char * dot_atom);
743
744void mailimf_quoted_string_free(char * quoted_string);
745
746void mailimf_word_free(char * word);
747
748void mailimf_phrase_free(char * phrase);
749
750void mailimf_unstructured_free(char * unstructured);
751
752void mailimf_angle_addr_free(char * angle_addr);
753
754void mailimf_display_name_free(char * display_name);
755
756void mailimf_addr_spec_free(char * addr_spec);
757
758void mailimf_local_part_free(char * local_part);
759
760void mailimf_domain_free(char * domain);
761
762void mailimf_domain_literal_free(char * domain);
763
764void mailimf_msg_id_free(char * msg_id);
765
766void mailimf_id_left_free(char * id_left);
767
768void mailimf_id_right_free(char * id_right);
769
770void mailimf_no_fold_quote_free(char * nfq);
771
772void mailimf_no_fold_literal_free(char * nfl);
773
774void mailimf_field_name_free(char * field_name);
775
776
777
778/* these are the possible returned error codes */
779
780enum {
781 MAILIMF_NO_ERROR = 0,
782 MAILIMF_ERROR_PARSE,
783 MAILIMF_ERROR_MEMORY,
784 MAILIMF_ERROR_INVAL,
785 MAILIMF_ERROR_FILE,
786};
787
788
789#ifdef __cplusplus
790}
791#endif
792
793#endif
diff --git a/kmicromail/libetpan/imf/mailimf_types_helper.c b/kmicromail/libetpan/imf/mailimf_types_helper.c
new file mode 100644
index 0000000..065b132
--- a/dev/null
+++ b/kmicromail/libetpan/imf/mailimf_types_helper.c
@@ -0,0 +1,1636 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include "mailimf_types_helper.h"
33
34#include <stdlib.h>
35#include <string.h>
36#include <time.h>
37#include <unistd.h>
38
39#include "mailimf.h"
40
41struct mailimf_mailbox_list *
42mailimf_mailbox_list_new_empty()
43{
44 clist * list;
45 struct mailimf_mailbox_list * mb_list;
46
47 list = clist_new();
48 if (list == NULL)
49 return NULL;
50
51 mb_list = mailimf_mailbox_list_new(list);
52 if (mb_list == NULL)
53 return NULL;
54
55 return mb_list;
56}
57
58int mailimf_mailbox_list_add(struct mailimf_mailbox_list * mailbox_list,
59 struct mailimf_mailbox * mb)
60{
61 int r;
62
63 r = clist_append(mailbox_list->mb_list, mb);
64 if (r < 0)
65 return MAILIMF_ERROR_MEMORY;
66
67 return MAILIMF_NO_ERROR;
68}
69
70int mailimf_mailbox_list_add_parse(struct mailimf_mailbox_list * mailbox_list,
71 char * mb_str)
72{
73 int r;
74 size_t cur_token;
75 struct mailimf_mailbox * mb;
76 int res;
77
78 cur_token = 0;
79 r = mailimf_mailbox_parse(mb_str, strlen(mb_str), &cur_token, &mb);
80 if (r != MAILIMF_NO_ERROR) {
81 res = r;
82 goto err;
83 }
84
85 r = mailimf_mailbox_list_add(mailbox_list, mb);
86 if (r != MAILIMF_NO_ERROR) {
87 res = r;
88 goto free;
89 }
90
91 return MAILIMF_NO_ERROR;
92
93 free:
94 mailimf_mailbox_free(mb);
95 err:
96 return res;
97}
98
99int mailimf_mailbox_list_add_mb(struct mailimf_mailbox_list * mailbox_list,
100 char * display_name, char * address)
101{
102 int r;
103 struct mailimf_mailbox * mb;
104 int res;
105
106 mb = mailimf_mailbox_new(display_name, address);
107 if (mb == NULL) {
108 res = MAILIMF_ERROR_MEMORY;
109 goto err;
110 }
111
112 r = mailimf_mailbox_list_add(mailbox_list, mb);
113 if (r != MAILIMF_NO_ERROR) {
114 res = r;
115 goto free;
116 }
117
118 return MAILIMF_NO_ERROR;
119
120 free:
121 mailimf_mailbox_free(mb);
122 err:
123 return res;
124}
125
126
127
128struct mailimf_address_list *
129mailimf_address_list_new_empty()
130{
131 clist * list;
132 struct mailimf_address_list * addr_list;
133
134 list = clist_new();
135 if (list == NULL)
136 return NULL;
137
138 addr_list = mailimf_address_list_new(list);
139 if (addr_list == NULL)
140 return NULL;
141
142 return addr_list;
143}
144
145int mailimf_address_list_add(struct mailimf_address_list * address_list,
146 struct mailimf_address * addr)
147{
148 int r;
149
150 r = clist_append(address_list->ad_list, addr);
151 if (r < 0)
152 return MAILIMF_ERROR_MEMORY;
153
154 return MAILIMF_NO_ERROR;
155}
156
157int mailimf_address_list_add_parse(struct mailimf_address_list * address_list,
158 char * addr_str)
159{
160 int r;
161 size_t cur_token;
162 struct mailimf_address * addr;
163 int res;
164
165 cur_token = 0;
166 r = mailimf_address_parse(addr_str, strlen(addr_str), &cur_token, &addr);
167 if (r != MAILIMF_NO_ERROR) {
168 res = r;
169 goto err;
170 }
171
172 r = mailimf_address_list_add(address_list, addr);
173 if (r != MAILIMF_NO_ERROR) {
174 res = r;
175 goto free;
176 }
177
178 return MAILIMF_NO_ERROR;
179
180 free:
181 mailimf_address_free(addr);
182 err:
183 return res;
184}
185
186int mailimf_address_list_add_mb(struct mailimf_address_list * address_list,
187 char * display_name, char * address)
188{
189 int r;
190 struct mailimf_mailbox * mb;
191 struct mailimf_address * addr;
192 int res;
193
194 mb = mailimf_mailbox_new(display_name, address);
195 if (mb == NULL) {
196 res = MAILIMF_ERROR_MEMORY;
197 goto err;
198 }
199
200 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
201 if (addr == NULL) {
202 res = MAILIMF_ERROR_MEMORY;
203 goto free_mb;
204 }
205
206 r = mailimf_address_list_add(address_list, addr);
207 if (r != MAILIMF_NO_ERROR) {
208 res = r;
209 goto free_addr;
210 }
211
212 return MAILIMF_NO_ERROR;
213
214 free_addr:
215 mailimf_address_free(addr);
216 free_mb:
217 mailimf_mailbox_free(mb);
218 err:
219 return res;
220}
221
222
223#if 0
224struct mailimf_resent_fields_list *
225mailimf_resent_fields_list_new_empty()
226{
227 clist * list;
228 struct mailimf_resent_fields_list * rf_list;
229
230 list = clist_new();
231 if (list == NULL)
232 return NULL;
233
234 rf_list = mailimf_resent_fields_list_new(list);
235 if (rf_list == NULL)
236 return NULL;
237
238 return rf_list;
239}
240
241int mailimf_resent_fields_add(struct mailimf_resent_fields_list * fields,
242 struct mailimf_resent_field * field)
243{
244 int r;
245
246 r = clist_append(fields->list, field);
247 if (r < 0)
248 return MAILIMF_ERROR_MEMORY;
249
250 return MAILIMF_NO_ERROR;
251}
252#endif
253
254
255static void detach_free_common_fields(struct mailimf_orig_date * imf_date,
256 struct mailimf_from * imf_from,
257 struct mailimf_sender * imf_sender,
258 struct mailimf_to * imf_to,
259 struct mailimf_cc * imf_cc,
260 struct mailimf_bcc * imf_bcc,
261 struct mailimf_message_id * imf_msg_id)
262{
263 if (imf_date != NULL) {
264 imf_date->dt_date_time = NULL;
265 mailimf_orig_date_free(imf_date);
266 }
267 if (imf_from != NULL) {
268 imf_from->frm_mb_list = NULL;
269 mailimf_from_free(imf_from);
270 }
271 if (imf_sender != NULL) {
272 imf_sender->snd_mb = NULL;
273 mailimf_sender_free(imf_sender);
274 }
275 if (imf_to != NULL) {
276 imf_to->to_addr_list = NULL;
277 mailimf_to_free(imf_to);
278 }
279 if (imf_cc != NULL) {
280 imf_cc->cc_addr_list = NULL;
281 mailimf_to_free(imf_to);
282 }
283 if (imf_bcc != NULL) {
284 imf_bcc->bcc_addr_list = NULL;
285 mailimf_bcc_free(imf_bcc);
286 }
287 if (imf_msg_id != NULL) {
288 imf_msg_id->mid_value = NULL;
289 mailimf_message_id_free(imf_msg_id);
290 }
291}
292
293static void detach_resent_field(struct mailimf_field * field)
294{
295 field->fld_type = MAILIMF_FIELD_NONE;
296 mailimf_field_free(field);
297}
298
299int
300mailimf_resent_fields_add_data(struct mailimf_fields * fields,
301 struct mailimf_date_time * resent_date,
302 struct mailimf_mailbox_list * resent_from,
303 struct mailimf_mailbox * resent_sender,
304 struct mailimf_address_list * resent_to,
305 struct mailimf_address_list * resent_cc,
306 struct mailimf_address_list * resent_bcc,
307 char * resent_msg_id)
308{
309 struct mailimf_orig_date * imf_resent_date;
310 struct mailimf_from * imf_resent_from;
311 struct mailimf_sender * imf_resent_sender;
312 struct mailimf_to * imf_resent_to;
313 struct mailimf_cc * imf_resent_cc;
314 struct mailimf_bcc * imf_resent_bcc;
315 struct mailimf_message_id * imf_resent_msg_id;
316 struct mailimf_field * field;
317 int r;
318
319 imf_resent_date = NULL;
320 imf_resent_from = NULL;
321 imf_resent_sender = NULL;
322 imf_resent_to = NULL;
323 imf_resent_cc = NULL;
324 imf_resent_bcc = NULL;
325 imf_resent_msg_id = NULL;
326 field = NULL;
327
328 if (resent_date != NULL) {
329 imf_resent_date = mailimf_orig_date_new(resent_date);
330 if (imf_resent_date == NULL)
331 goto free;
332 field = mailimf_field_new(MAILIMF_FIELD_RESENT_DATE,
333 NULL /* return-path */,
334 imf_resent_date /* resent date */,
335 NULL /* resent from */,
336 NULL /* resent sender */,
337 NULL /* resent to */,
338 NULL /* resent cc */,
339 NULL /* resent bcc */,
340 NULL /* resent msg id */,
341 NULL /* date */,
342 NULL /* from */,
343 NULL /* sender */,
344 NULL /* reply-to */,
345 NULL /* to */,
346 NULL /* cc */,
347 NULL /* bcc */,
348 NULL /* message id */,
349 NULL /* in reply to */,
350 NULL /* references */,
351 NULL /* subject */,
352 NULL /* comments */,
353 NULL /* keywords */,
354 NULL /* optional field */);
355 if (field == NULL)
356 goto free;
357 r = mailimf_fields_add(fields, field);
358 if (r != MAILIMF_NO_ERROR)
359 goto free_field;
360 }
361
362 if (resent_from != NULL) {
363 imf_resent_from = mailimf_from_new(resent_from);
364 if (imf_resent_from == NULL)
365 goto free_field;
366 field = mailimf_field_new(MAILIMF_FIELD_RESENT_FROM,
367 NULL /* return-path */,
368 NULL /* resent date */,
369 imf_resent_from /* resent from */,
370 NULL /* resent sender */,
371 NULL /* resent to */,
372 NULL /* resent cc */,
373 NULL /* resent bcc */,
374 NULL /* resent msg id */,
375 NULL /* date */,
376 NULL /* from */,
377 NULL /* sender */,
378 NULL /* reply-to */,
379 NULL /* to */,
380 NULL /* cc */,
381 NULL /* bcc */,
382 NULL /* message id */,
383 NULL /* in reply to */,
384 NULL /* references */,
385 NULL /* subject */,
386 NULL /* comments */,
387 NULL /* keywords */,
388 NULL /* optional field */);
389 if (field == NULL)
390 goto free;
391 r = mailimf_fields_add(fields, field);
392 if (r != MAILIMF_NO_ERROR)
393 goto free_field;
394 }
395
396 if (resent_sender != NULL) {
397 imf_resent_sender = mailimf_sender_new(resent_sender);
398 if (imf_resent_sender == NULL)
399 goto free;
400 field = mailimf_field_new(MAILIMF_FIELD_RESENT_SENDER,
401 NULL /* return-path */,
402 NULL /* resent date */,
403 NULL /* resent from */,
404 imf_resent_sender /* resent sender */,
405 NULL /* resent to */,
406 NULL /* resent cc */,
407 NULL /* resent bcc */,
408 NULL /* resent msg id */,
409 NULL /* date */,
410 NULL /* from */,
411 NULL /* sender */,
412 NULL /* reply-to */,
413 NULL /* to */,
414 NULL /* cc */,
415 NULL /* bcc */,
416 NULL /* message id */,
417 NULL /* in reply to */,
418 NULL /* references */,
419 NULL /* subject */,
420 NULL /* comments */,
421 NULL /* keywords */,
422 NULL /* optional field */);
423 if (field == NULL)
424 goto free;
425 r = mailimf_fields_add(fields, field);
426 if (r != MAILIMF_NO_ERROR)
427 goto free_field;
428 }
429
430 if (resent_to != NULL) {
431 imf_resent_to = mailimf_to_new(resent_to);
432 if (imf_resent_to == NULL)
433 goto free;
434 field = mailimf_field_new(MAILIMF_FIELD_RESENT_TO,
435 NULL /* return-path */,
436 NULL /* resent date */,
437 NULL /* resent from */,
438 NULL /* resent sender */,
439 imf_resent_to /* resent to */,
440 NULL /* resent cc */,
441 NULL /* resent bcc */,
442 NULL /* resent msg id */,
443 NULL /* date */,
444 NULL /* from */,
445 NULL /* sender */,
446 NULL /* reply-to */,
447 NULL /* to */,
448 NULL /* cc */,
449 NULL /* bcc */,
450 NULL /* message id */,
451 NULL /* in reply to */,
452 NULL /* references */,
453 NULL /* subject */,
454 NULL /* comments */,
455 NULL /* keywords */,
456 NULL /* optional field */);
457 if (field == NULL)
458 goto free;
459 r = mailimf_fields_add(fields, field);
460 if (r != MAILIMF_NO_ERROR)
461 goto free_field;
462 }
463
464 if (resent_cc != NULL) {
465 imf_resent_cc = mailimf_cc_new(resent_cc);
466 if (imf_resent_cc == NULL)
467 goto free;
468 field = mailimf_field_new(MAILIMF_FIELD_RESENT_CC,
469 NULL /* return-path */,
470 NULL /* resent date */,
471 NULL /* resent from */,
472 NULL /* resent sender */,
473 NULL /* resent to */,
474 imf_resent_cc /* resent cc */,
475 NULL /* resent bcc */,
476 NULL /* resent msg id */,
477 NULL /* date */,
478 NULL /* from */,
479 NULL /* sender */,
480 NULL /* reply-to */,
481 NULL /* to */,
482 NULL /* cc */,
483 NULL /* bcc */,
484 NULL /* message id */,
485 NULL /* in reply to */,
486 NULL /* references */,
487 NULL /* subject */,
488 NULL /* comments */,
489 NULL /* keywords */,
490 NULL /* optional field */);
491 if (field == NULL)
492 goto free;
493 r = mailimf_fields_add(fields, field);
494 if (r != MAILIMF_NO_ERROR)
495 goto free_field;
496 }
497
498 if (resent_bcc != NULL) {
499 imf_resent_bcc = mailimf_bcc_new(resent_bcc);
500 if (imf_resent_bcc == NULL)
501 goto free;
502 field = mailimf_field_new(MAILIMF_FIELD_RESENT_BCC,
503 NULL /* return-path */,
504 NULL /* resent date */,
505 NULL /* resent from */,
506 NULL /* resent sender */,
507 NULL /* resent to */,
508 NULL /* resent cc */,
509 imf_resent_bcc /* resent bcc */,
510 NULL /* resent msg id */,
511 NULL /* date */,
512 NULL /* from */,
513 NULL /* sender */,
514 NULL /* reply-to */,
515 NULL /* to */,
516 NULL /* cc */,
517 NULL /* bcc */,
518 NULL /* message id */,
519 NULL /* in reply to */,
520 NULL /* references */,
521 NULL /* subject */,
522 NULL /* comments */,
523 NULL /* keywords */,
524 NULL /* optional field */);
525 if (field == NULL)
526 goto free;
527 r = mailimf_fields_add(fields, field);
528 if (r != MAILIMF_NO_ERROR)
529 goto free_field;
530 }
531
532 if (resent_msg_id != NULL) {
533 imf_resent_msg_id = mailimf_message_id_new(resent_msg_id);
534 if (imf_resent_msg_id == NULL)
535 goto free;
536 field = mailimf_field_new(MAILIMF_FIELD_RESENT_MSG_ID,
537 NULL /* return-path */,
538 NULL /* resent date */,
539 NULL /* resent from */,
540 NULL /* resent sender */,
541 NULL /* resent to */,
542 NULL /* resent cc */,
543 NULL /* resent bcc */,
544 imf_resent_msg_id /* resent msg id */,
545 NULL /* date */,
546 NULL /* from */,
547 NULL /* sender */,
548 NULL /* reply-to */,
549 NULL /* to */,
550 NULL /* cc */,
551 NULL /* bcc */,
552 NULL /* message id */,
553 NULL /* in reply to */,
554 NULL /* references */,
555 NULL /* subject */,
556 NULL /* comments */,
557 NULL /* keywords */,
558 NULL /* optional field */);
559 if (field == NULL)
560 goto free;
561 r = mailimf_fields_add(fields, field);
562 if (r != MAILIMF_NO_ERROR)
563 goto free_field;
564 }
565
566 return MAILIMF_NO_ERROR;
567
568 free_field:
569 if (field != NULL) {
570 detach_resent_field(field);
571 mailimf_field_free(field);
572 }
573 free:
574 detach_free_common_fields(imf_resent_date,
575 imf_resent_from,
576 imf_resent_sender,
577 imf_resent_to,
578 imf_resent_cc,
579 imf_resent_bcc,
580 imf_resent_msg_id);
581 return MAILIMF_ERROR_MEMORY;
582}
583
584struct mailimf_fields *
585mailimf_resent_fields_new_with_data_all(struct mailimf_date_time *
586 resent_date,
587 struct mailimf_mailbox_list *
588 resent_from,
589 struct mailimf_mailbox *
590 resent_sender,
591 struct mailimf_address_list *
592 resent_to,
593 struct mailimf_address_list *
594 resent_cc,
595 struct mailimf_address_list *
596 resent_bcc,
597 char * resent_msg_id)
598{
599 struct mailimf_fields * resent_fields;
600 int r;
601
602 resent_fields = mailimf_fields_new_empty();
603 if (resent_fields == NULL)
604 goto err;
605
606 r = mailimf_resent_fields_add_data(resent_fields,
607 resent_date, resent_from,
608 resent_sender, resent_to,
609 resent_cc, resent_bcc,
610 resent_msg_id);
611 if (r != MAILIMF_NO_ERROR)
612 goto free;
613
614 return resent_fields;
615
616 free:
617 mailimf_fields_free(resent_fields);
618 err:
619 return NULL;
620}
621
622
623struct mailimf_fields *
624mailimf_resent_fields_new_with_data(struct mailimf_mailbox_list * from,
625 struct mailimf_mailbox * sender,
626 struct mailimf_address_list * to,
627 struct mailimf_address_list * cc,
628 struct mailimf_address_list * bcc)
629{
630 struct mailimf_date_time * date;
631 char * msg_id;
632 struct mailimf_fields * fields;
633
634 date = mailimf_get_current_date();
635 if (date == NULL)
636 goto err;
637
638 msg_id = mailimf_get_message_id();
639 if (msg_id == NULL)
640 goto free_date;
641
642 fields = mailimf_resent_fields_new_with_data_all(date,
643 from, sender, to, cc, bcc, msg_id);
644 if (fields == NULL)
645 goto free_msg_id;
646
647 return fields;
648
649 free_msg_id:
650 free(msg_id);
651 free_date:
652 mailimf_date_time_free(date);
653 err:
654 return NULL;
655}
656
657
658struct mailimf_fields *
659mailimf_fields_new_empty(void)
660{
661 clist * list;
662 struct mailimf_fields * fields_list;
663
664 list = clist_new();
665 if (list == NULL)
666 return NULL;
667
668 fields_list = mailimf_fields_new(list);
669 if (fields_list == NULL)
670 return NULL;
671
672 return fields_list;
673}
674
675int mailimf_fields_add(struct mailimf_fields * fields,
676 struct mailimf_field * field)
677{
678 int r;
679
680 r = clist_append(fields->fld_list, field);
681 if (r < 0)
682 return MAILIMF_ERROR_MEMORY;
683
684 return MAILIMF_NO_ERROR;
685}
686
687static void detach_free_fields(struct mailimf_orig_date * date,
688 struct mailimf_from * from,
689 struct mailimf_sender * sender,
690 struct mailimf_reply_to * reply_to,
691 struct mailimf_to * to,
692 struct mailimf_cc * cc,
693 struct mailimf_bcc * bcc,
694 struct mailimf_message_id * msg_id,
695 struct mailimf_in_reply_to * in_reply_to,
696 struct mailimf_references * references,
697 struct mailimf_subject * subject)
698{
699 detach_free_common_fields(date,
700 from,
701 sender,
702 to,
703 cc,
704 bcc,
705 msg_id);
706
707 if (reply_to != NULL) {
708 reply_to->rt_addr_list = NULL;
709 mailimf_reply_to_free(reply_to);
710 }
711
712 if (in_reply_to != NULL) {
713 in_reply_to->mid_list = NULL;
714 mailimf_in_reply_to_free(in_reply_to);
715 }
716
717 if (references != NULL) {
718 references->mid_list = NULL;
719 mailimf_references_free(references);
720 }
721
722 if (subject != NULL) {
723 subject->sbj_value = NULL;
724 mailimf_subject_free(subject);
725 }
726}
727
728
729static void detach_field(struct mailimf_field * field)
730{
731 field->fld_type = MAILIMF_FIELD_NONE;
732 mailimf_field_free(field);
733}
734
735int mailimf_fields_add_data(struct mailimf_fields * fields,
736 struct mailimf_date_time * date,
737 struct mailimf_mailbox_list * from,
738 struct mailimf_mailbox * sender,
739 struct mailimf_address_list * reply_to,
740 struct mailimf_address_list * to,
741 struct mailimf_address_list * cc,
742 struct mailimf_address_list * bcc,
743 char * msg_id,
744 clist * in_reply_to,
745 clist * references,
746 char * subject)
747{
748 struct mailimf_orig_date * imf_date;
749 struct mailimf_from * imf_from;
750 struct mailimf_sender * imf_sender;
751 struct mailimf_reply_to * imf_reply_to;
752 struct mailimf_to * imf_to;
753 struct mailimf_cc * imf_cc;
754 struct mailimf_bcc * imf_bcc;
755 struct mailimf_message_id * imf_msg_id;
756 struct mailimf_references * imf_references;
757 struct mailimf_in_reply_to * imf_in_reply_to;
758 struct mailimf_subject * imf_subject;
759 struct mailimf_field * field;
760 int r;
761
762 imf_date = NULL;
763 imf_from = NULL;
764 imf_sender = NULL;
765 imf_reply_to = NULL;
766 imf_to = NULL;
767 imf_cc = NULL;
768 imf_bcc = NULL;
769 imf_msg_id = NULL;
770 imf_references = NULL;
771 imf_in_reply_to = NULL;
772 imf_subject =NULL;
773 field = NULL;
774
775 if (date != NULL) {
776 imf_date = mailimf_orig_date_new(date);
777 if (imf_date == NULL)
778 goto free;
779 field = mailimf_field_new(MAILIMF_FIELD_ORIG_DATE,
780 NULL /* return-path */,
781 NULL /* resent date */,
782 NULL /* resent from */,
783 NULL /* resent sender */,
784 NULL /* resent to */,
785 NULL /* resent cc */,
786 NULL /* resent bcc */,
787 NULL /* resent msg id */,
788 imf_date /* date */,
789 NULL /* from */,
790 NULL /* sender */,
791 NULL /* reply-to */,
792 NULL /* to */,
793 NULL /* cc */,
794 NULL /* bcc */,
795 NULL /* message id */,
796 NULL /* in reply to */,
797 NULL /* references */,
798 NULL /* subject */,
799 NULL /* comments */,
800 NULL /* keywords */,
801 NULL /* optional field */);
802 if (field == NULL)
803 goto free;
804 r = mailimf_fields_add(fields, field);
805 if (r != MAILIMF_NO_ERROR)
806 goto free_field;
807 }
808
809 if (from != NULL) {
810 imf_from = mailimf_from_new(from);
811 if (imf_from == NULL)
812 goto free_field;
813 field = mailimf_field_new(MAILIMF_FIELD_FROM,
814 NULL /* return-path */,
815 NULL /* resent date */,
816 NULL /* resent from */,
817 NULL /* resent sender */,
818 NULL /* resent to */,
819 NULL /* resent cc */,
820 NULL /* resent bcc */,
821 NULL /* resent msg id */,
822 NULL /* date */,
823 imf_from /* from */,
824 NULL /* sender */,
825 NULL /* reply-to */,
826 NULL /* to */,
827 NULL /* cc */,
828 NULL /* bcc */,
829 NULL /* message id */,
830 NULL /* in reply to */,
831 NULL /* references */,
832 NULL /* subject */,
833 NULL /* comments */,
834 NULL /* keywords */,
835 NULL /* optional field */);
836 if (field == NULL)
837 goto free;
838 r = mailimf_fields_add(fields, field);
839 if (r != MAILIMF_NO_ERROR)
840 goto free_field;
841 }
842
843 if (sender != NULL) {
844 imf_sender = mailimf_sender_new(sender);
845 if (imf_sender == NULL)
846 goto free;
847 field = mailimf_field_new(MAILIMF_FIELD_SENDER,
848 NULL /* return-path */,
849 NULL /* resent date */,
850 NULL /* resent from */,
851 NULL /* resent sender */,
852 NULL /* resent to */,
853 NULL /* resent cc */,
854 NULL /* resent bcc */,
855 NULL /* resent msg id */,
856 NULL /* date */,
857 NULL /* from */,
858 imf_sender /* sender */,
859 NULL /* reply-to */,
860 NULL /* to */,
861 NULL /* cc */,
862 NULL /* bcc */,
863 NULL /* message id */,
864 NULL /* in reply to */,
865 NULL /* references */,
866 NULL /* subject */,
867 NULL /* comments */,
868 NULL /* keywords */,
869 NULL /* optional field */);
870 if (field == NULL)
871 goto free;
872 r = mailimf_fields_add(fields, field);
873 if (r != MAILIMF_NO_ERROR)
874 goto free_field;
875 }
876
877 if (reply_to != NULL) {
878 imf_reply_to = mailimf_reply_to_new(reply_to);
879 if (imf_reply_to == NULL)
880 goto free;
881 field = mailimf_field_new(MAILIMF_FIELD_REPLY_TO,
882 NULL /* return-path */,
883 NULL /* resent date */,
884 NULL /* resent from */,
885 NULL /* resent sender */,
886 NULL /* resent to */,
887 NULL /* resent cc */,
888 NULL /* resent bcc */,
889 NULL /* resent msg id */,
890 NULL /* date */,
891 NULL /* from */,
892 NULL /* sender */,
893 imf_reply_to /* reply-to */,
894 NULL /* to */,
895 NULL /* cc */,
896 NULL /* bcc */,
897 NULL /* message id */,
898 NULL /* in reply to */,
899 NULL /* references */,
900 NULL /* subject */,
901 NULL /* comments */,
902 NULL /* keywords */,
903 NULL /* optional field */);
904 if (field == NULL)
905 goto free;
906 r = mailimf_fields_add(fields, field);
907 if (r != MAILIMF_NO_ERROR)
908 goto free_field;
909 }
910
911 if (to != NULL) {
912 imf_to = mailimf_to_new(to);
913 if (imf_to == NULL)
914 goto free;
915 field = mailimf_field_new(MAILIMF_FIELD_TO,
916 NULL /* return-path */,
917 NULL /* resent date */,
918 NULL /* resent from */,
919 NULL /* resent sender */,
920 NULL /* resent to */,
921 NULL /* resent cc */,
922 NULL /* resent bcc */,
923 NULL /* resent msg id */,
924 NULL /* date */,
925 NULL /* from */,
926 NULL /* sender */,
927 NULL /* reply-to */,
928 imf_to /* to */,
929 NULL /* cc */,
930 NULL /* bcc */,
931 NULL /* message id */,
932 NULL /* in reply to */,
933 NULL /* references */,
934 NULL /* subject */,
935 NULL /* comments */,
936 NULL /* keywords */,
937 NULL /* optional field */);
938 if (field == NULL)
939 goto free;
940 r = mailimf_fields_add(fields, field);
941 if (r != MAILIMF_NO_ERROR)
942 goto free_field;
943 }
944
945 if (cc != NULL) {
946 imf_cc = mailimf_cc_new(cc);
947 if (imf_cc == NULL)
948 goto free;
949 field = mailimf_field_new(MAILIMF_FIELD_CC,
950 NULL /* return-path */,
951 NULL /* resent date */,
952 NULL /* resent from */,
953 NULL /* resent sender */,
954 NULL /* resent to */,
955 NULL /* resent cc */,
956 NULL /* resent bcc */,
957 NULL /* resent msg id */,
958 NULL /* date */,
959 NULL /* from */,
960 NULL /* sender */,
961 NULL /* reply-to */,
962 NULL /* to */,
963 imf_cc /* cc */,
964 NULL /* bcc */,
965 NULL /* message id */,
966 NULL /* in reply to */,
967 NULL /* references */,
968 NULL /* subject */,
969 NULL /* comments */,
970 NULL /* keywords */,
971 NULL /* optional field */);
972 if (field == NULL)
973 goto free;
974 r = mailimf_fields_add(fields, field);
975 if (r != MAILIMF_NO_ERROR)
976 goto free_field;
977 }
978
979 if (bcc != NULL) {
980 imf_bcc = mailimf_bcc_new(bcc);
981 if (imf_bcc == NULL)
982 goto free;
983 field = mailimf_field_new(MAILIMF_FIELD_BCC,
984 NULL /* return-path */,
985 NULL /* resent date */,
986 NULL /* resent from */,
987 NULL /* resent sender */,
988 NULL /* resent to */,
989 NULL /* resent cc */,
990 NULL /* resent bcc */,
991 NULL /* resent msg id */,
992 NULL /* date */,
993 NULL /* from */,
994 NULL /* sender */,
995 NULL /* reply-to */,
996 NULL /* to */,
997 NULL /* cc */,
998 imf_bcc /* bcc */,
999 NULL /* message id */,
1000 NULL /* in reply to */,
1001 NULL /* references */,
1002 NULL /* subject */,
1003 NULL /* comments */,
1004 NULL /* keywords */,
1005 NULL /* optional field */);
1006 if (field == NULL)
1007 goto free;
1008 r = mailimf_fields_add(fields, field);
1009 if (r != MAILIMF_NO_ERROR)
1010 goto free_field;
1011 }
1012
1013 if (msg_id != NULL) {
1014 imf_msg_id = mailimf_message_id_new(msg_id);
1015 if (imf_msg_id == NULL)
1016 goto free;
1017 field = mailimf_field_new(MAILIMF_FIELD_MESSAGE_ID,
1018 NULL /* return-path */,
1019 NULL /* resent date */,
1020 NULL /* resent from */,
1021 NULL /* resent sender */,
1022 NULL /* resent to */,
1023 NULL /* resent cc */,
1024 NULL /* resent bcc */,
1025 NULL /* resent msg id */,
1026 NULL /* date */,
1027 NULL /* from */,
1028 NULL /* sender */,
1029 NULL /* reply-to */,
1030 NULL /* to */,
1031 NULL /* cc */,
1032 NULL /* bcc */,
1033 imf_msg_id /* message id */,
1034 NULL /* in reply to */,
1035 NULL /* references */,
1036 NULL /* subject */,
1037 NULL /* comments */,
1038 NULL /* keywords */,
1039 NULL /* optional field */);
1040 if (field == NULL)
1041 goto free;
1042 r = mailimf_fields_add(fields, field);
1043 if (r != MAILIMF_NO_ERROR)
1044 goto free_field;
1045 }
1046
1047 if (in_reply_to != NULL) {
1048 imf_in_reply_to = mailimf_in_reply_to_new(in_reply_to);
1049 if (imf_in_reply_to == NULL)
1050 goto free;
1051 field = mailimf_field_new(MAILIMF_FIELD_IN_REPLY_TO,
1052 NULL /* return-path */,
1053 NULL /* resent date */,
1054 NULL /* resent from */,
1055 NULL /* resent sender */,
1056 NULL /* resent to */,
1057 NULL /* resent cc */,
1058 NULL /* resent bcc */,
1059 NULL /* resent msg id */,
1060 NULL /* date */,
1061 NULL /* from */,
1062 NULL /* sender */,
1063 NULL /* reply-to */,
1064 NULL /* to */,
1065 NULL /* cc */,
1066 NULL /* bcc */,
1067 NULL /* message id */,
1068 imf_in_reply_to /* in reply to */,
1069 NULL /* references */,
1070 NULL /* subject */,
1071 NULL /* comments */,
1072 NULL /* keywords */,
1073 NULL /* optional field */);
1074 if (field == NULL)
1075 goto free;
1076 r = mailimf_fields_add(fields, field);
1077 if (r != MAILIMF_NO_ERROR)
1078 goto free_field;
1079 }
1080
1081 if (references != NULL) {
1082 imf_references = mailimf_references_new(references);
1083 if (imf_references == NULL)
1084 goto free;
1085 field = mailimf_field_new(MAILIMF_FIELD_REFERENCES,
1086 NULL /* return-path */,
1087 NULL /* resent date */,
1088 NULL /* resent from */,
1089 NULL /* resent sender */,
1090 NULL /* resent to */,
1091 NULL /* resent cc */,
1092 NULL /* resent bcc */,
1093 NULL /* resent msg id */,
1094 NULL /* date */,
1095 NULL /* from */,
1096 NULL /* sender */,
1097 NULL /* reply-to */,
1098 NULL /* to */,
1099 NULL /* cc */,
1100 NULL /* bcc */,
1101 NULL /* message id */,
1102 NULL /* in reply to */,
1103 imf_references /* references */,
1104 NULL /* subject */,
1105 NULL /* comments */,
1106 NULL /* keywords */,
1107 NULL /* optional field */);
1108 if (field == NULL)
1109 goto free;
1110 r = mailimf_fields_add(fields, field);
1111 if (r != MAILIMF_NO_ERROR)
1112 goto free_field;
1113 }
1114
1115 if (subject != NULL) {
1116 imf_subject = mailimf_subject_new(subject);
1117 if (imf_subject == NULL)
1118 goto free;
1119 field = mailimf_field_new(MAILIMF_FIELD_SUBJECT,
1120 NULL /* return-path */,
1121 NULL /* resent date */,
1122 NULL /* resent from */,
1123 NULL /* resent sender */,
1124 NULL /* resent to */,
1125 NULL /* resent cc */,
1126 NULL /* resent bcc */,
1127 NULL /* resent msg id */,
1128 NULL /* date */,
1129 NULL /* from */,
1130 NULL /* sender */,
1131 NULL /* reply-to */,
1132 NULL /* to */,
1133 NULL /* cc */,
1134 NULL /* bcc */,
1135 NULL /* message id */,
1136 NULL /* in reply to */,
1137 NULL /* references */,
1138 imf_subject /* subject */,
1139 NULL /* comments */,
1140 NULL /* keywords */,
1141 NULL /* optional field */);
1142 if (field == NULL)
1143 goto free;
1144 r = mailimf_fields_add(fields, field);
1145 if (r != MAILIMF_NO_ERROR)
1146 goto free_field;
1147 }
1148
1149 return MAILIMF_NO_ERROR;
1150
1151 free_field:
1152 if (field != NULL) {
1153 detach_field(field);
1154 mailimf_field_free(field);
1155 }
1156 free:
1157 detach_free_fields(imf_date,
1158 imf_from,
1159 imf_sender,
1160 imf_reply_to,
1161 imf_to,
1162 imf_cc,
1163 imf_bcc,
1164 imf_msg_id,
1165 imf_in_reply_to,
1166 imf_references,
1167 imf_subject);
1168
1169 return MAILIMF_ERROR_MEMORY;
1170}
1171
1172struct mailimf_fields *
1173mailimf_fields_new_with_data_all(struct mailimf_date_time * date,
1174 struct mailimf_mailbox_list * from,
1175 struct mailimf_mailbox * sender,
1176 struct mailimf_address_list * reply_to,
1177 struct mailimf_address_list * to,
1178 struct mailimf_address_list * cc,
1179 struct mailimf_address_list * bcc,
1180 char * message_id,
1181 clist * in_reply_to,
1182 clist * references,
1183 char * subject)
1184{
1185 struct mailimf_fields * fields;
1186 int r;
1187
1188 fields = mailimf_fields_new_empty();
1189 if (fields == NULL)
1190 goto err;
1191
1192 r = mailimf_fields_add_data(fields,
1193 date,
1194 from,
1195 sender,
1196 reply_to,
1197 to,
1198 cc,
1199 bcc,
1200 message_id,
1201 in_reply_to,
1202 references,
1203 subject);
1204 if (r != MAILIMF_NO_ERROR)
1205 goto free;
1206
1207 return fields;
1208
1209 free:
1210 mailimf_fields_free(fields);
1211 err:
1212 return NULL;
1213}
1214
1215struct mailimf_fields *
1216mailimf_fields_new_with_data(struct mailimf_mailbox_list * from,
1217 struct mailimf_mailbox * sender,
1218 struct mailimf_address_list * reply_to,
1219 struct mailimf_address_list * to,
1220 struct mailimf_address_list * cc,
1221 struct mailimf_address_list * bcc,
1222 clist * in_reply_to,
1223 clist * references,
1224 char * subject)
1225{
1226 struct mailimf_date_time * date;
1227 char * msg_id;
1228 struct mailimf_fields * fields;
1229
1230 date = mailimf_get_current_date();
1231 if (date == NULL)
1232 goto err;
1233
1234 msg_id = mailimf_get_message_id();
1235 if (msg_id == NULL)
1236 goto free_date;
1237
1238 fields = mailimf_fields_new_with_data_all(date,
1239 from, sender, reply_to,
1240 to, cc, bcc,
1241 msg_id,
1242 in_reply_to, references,
1243 subject);
1244 if (fields == NULL)
1245 goto free_msg_id;
1246
1247 return fields;
1248
1249 free_msg_id:
1250 free(msg_id);
1251 free_date:
1252 mailimf_date_time_free(date);
1253 err:
1254 return NULL;
1255}
1256
1257
1258
1259#define MAX_MESSAGE_ID 512
1260
1261char * mailimf_get_message_id(void)
1262{
1263 char id[MAX_MESSAGE_ID];
1264 time_t now;
1265 char name[MAX_MESSAGE_ID];
1266 long value;
1267
1268 now = time(NULL);
1269 value = random();
1270
1271 gethostname(name, MAX_MESSAGE_ID);
1272 snprintf(id, MAX_MESSAGE_ID, "etPan.%lx.%lx.%x@%s",
1273 now, value, getpid(), name);
1274
1275 return strdup(id);
1276}
1277
1278
1279
1280static time_t mkgmtime(struct tm * tmp);
1281
1282
1283struct mailimf_date_time * mailimf_get_current_date(void)
1284{
1285 struct tm gmt;
1286 struct tm lt;
1287 int off;
1288 time_t now;
1289 struct mailimf_date_time * date_time;
1290
1291 now = time(NULL);
1292
1293 if (gmtime_r(&now, &gmt) == NULL)
1294 return NULL;
1295
1296 if (localtime_r(&now, &lt) == NULL)
1297 return NULL;
1298
1299 off = (mkgmtime(&lt) - mkgmtime(&gmt)) / (60 * 60) * 100;
1300
1301 date_time = mailimf_date_time_new(lt.tm_mday, lt.tm_mon + 1, lt.tm_year + 1900,
1302 lt.tm_hour, lt.tm_min, lt.tm_sec,
1303 off);
1304
1305 return date_time;
1306}
1307
1308
1309
1310/* mkgmtime.c - make time corresponding to a GMT timeval struct
1311 $Id$
1312
1313 * Copyright (c) 1998-2000 Carnegie Mellon University. All rights reserved.
1314 *
1315 * Redistribution and use in source and binary forms, with or without
1316 * modification, are permitted provided that the following conditions
1317 * are met:
1318 *
1319 * 1. Redistributions of source code must retain the above copyright
1320 * notice, this list of conditions and the following disclaimer.
1321 *
1322 * 2. Redistributions in binary form must reproduce the above copyright
1323 * notice, this list of conditions and the following disclaimer in
1324 * the documentation and/or other materials provided with the
1325 * distribution.
1326 *
1327 * 3. The name "Carnegie Mellon University" must not be used to
1328 * endorse or promote products derived from this software without
1329 * prior written permission. For permission or any other legal
1330 * details, please contact
1331 * Office of Technology Transfer
1332 * Carnegie Mellon University
1333 * 5000 Forbes Avenue
1334 * Pittsburgh, PA 15213-3890
1335 * (412) 268-4387, fax: (412) 268-7395
1336 * tech-transfer@andrew.cmu.edu
1337 *
1338 * 4. Redistributions of any form whatsoever must retain the following
1339 * acknowledgment:
1340 * "This product includes software developed by Computing Services
1341 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
1342 *
1343 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
1344 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1345 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
1346 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1347 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
1348 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
1349 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1350 *
1351 *
1352 */
1353/*
1354 * Copyright (c) 1987, 1989, 1993
1355 *The Regents of the University of California. All rights reserved.
1356 *
1357 * This code is derived from software contributed to Berkeley by
1358 * Arthur David Olson of the National Cancer Institute.
1359 *
1360 * Redistribution and use in source and binary forms, with or without
1361 * modification, are permitted provided that the following conditions
1362 * are met:
1363 * 1. Redistributions of source code must retain the above copyright
1364 * notice, this list of conditions and the following disclaimer.
1365 * 2. Redistributions in binary form must reproduce the above copyright
1366 * notice, this list of conditions and the following disclaimer in the
1367 * documentation and/or other materials provided with the distribution.
1368 * 3. All advertising materials mentioning features or use of this software
1369 * must display the following acknowledgement:
1370 *This product includes software developed by the University of
1371 *California, Berkeley and its contributors.
1372 * 4. Neither the name of the University nor the names of its contributors
1373 * may be used to endorse or promote products derived from this software
1374 * without specific prior written permission.
1375 *
1376 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1377 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1378 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1379 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1380 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1381 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1382 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1383 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1384 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1385 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1386 * SUCH DAMAGE.
1387 */
1388
1389/*
1390** Adapted from code provided by Robert Elz, who writes:
1391 **The "best" way to do mktime I think is based on an idea of Bob
1392 **Kridle's (so its said...) from a long time ago. (mtxinu!kridle now).
1393 **It does a binary search of the time_t space. Since time_t's are
1394 **just 32 bits, its a max of 32 iterations (even at 64 bits it
1395 **would still be very reasonable).
1396*/
1397
1398/*
1399 adapted for libEtPan! by DINH V. Hoa
1400*/
1401
1402#ifndef WRONG
1403 #define WRONG(-1)
1404#endif /* !defined WRONG */
1405
1406static int tmcomp(struct tm * atmp, struct tm * btmp)
1407{
1408 register intresult;
1409
1410 if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
1411 (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
1412 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
1413 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
1414 (result = (atmp->tm_min - btmp->tm_min)) == 0)
1415 result = atmp->tm_sec - btmp->tm_sec;
1416 return result;
1417}
1418
1419static time_t mkgmtime(struct tm * tmp)
1420{
1421 register int dir;
1422 register int bits;
1423 register int saved_seconds;
1424 time_t t;
1425 struct tm yourtm, *mytm;
1426
1427 yourtm = *tmp;
1428 saved_seconds = yourtm.tm_sec;
1429 yourtm.tm_sec = 0;
1430 /*
1431 ** Calculate the number of magnitude bits in a time_t
1432 ** (this works regardless of whether time_t is
1433 ** signed or unsigned, though lint complains if unsigned).
1434 */
1435 for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
1436 ;
1437 /*
1438 ** If time_t is signed, then 0 is the median value,
1439 ** if time_t is unsigned, then 1 << bits is median.
1440 */
1441 t = (t < 0) ? 0 : ((time_t) 1 << bits);
1442 for ( ; ; ) {
1443 mytm = gmtime(&t);
1444 dir = tmcomp(mytm, &yourtm);
1445 if (dir != 0) {
1446 if (bits-- < 0)
1447 return WRONG;
1448 if (bits < 0)
1449 --t;
1450 else if (dir > 0)
1451 t -= (time_t) 1 << bits;
1452 elset += (time_t) 1 << bits;
1453 continue;
1454 }
1455 break;
1456 }
1457 t += saved_seconds;
1458 return t;
1459}
1460
1461
1462
1463
1464
1465
1466
1467void mailimf_single_fields_init(struct mailimf_single_fields * single_fields,
1468 struct mailimf_fields * fields)
1469{
1470 clistiter * cur;
1471
1472 memset(single_fields, 0, sizeof(struct mailimf_single_fields));
1473
1474 cur = clist_begin(fields->fld_list);
1475 while (cur != NULL) {
1476 struct mailimf_field * field;
1477
1478 field = clist_content(cur);
1479
1480 switch (field->fld_type) {
1481 case MAILIMF_FIELD_ORIG_DATE:
1482 if (single_fields->fld_orig_date == NULL)
1483 single_fields->fld_orig_date = field->fld_data.fld_orig_date;
1484 cur = clist_next(cur);
1485 break;
1486 case MAILIMF_FIELD_FROM:
1487 if (single_fields->fld_from == NULL) {
1488 single_fields->fld_from = field->fld_data.fld_from;
1489 cur = clist_next(cur);
1490 }
1491 else {
1492 clist_concat(single_fields->fld_from->frm_mb_list->mb_list,
1493 field->fld_data.fld_from->frm_mb_list->mb_list);
1494 mailimf_field_free(field);
1495 cur = clist_delete(fields->fld_list, cur);
1496 }
1497 break;
1498 case MAILIMF_FIELD_SENDER:
1499 if (single_fields->fld_sender == NULL)
1500 single_fields->fld_sender = field->fld_data.fld_sender;
1501 cur = clist_next(cur);
1502 break;
1503 case MAILIMF_FIELD_REPLY_TO:
1504 if (single_fields->fld_reply_to == NULL) {
1505 single_fields->fld_reply_to = field->fld_data.fld_reply_to;
1506 cur = clist_next(cur);
1507 }
1508 else {
1509 clist_concat(single_fields->fld_reply_to->rt_addr_list->ad_list,
1510 field->fld_data.fld_reply_to->rt_addr_list->ad_list);
1511 mailimf_field_free(field);
1512 cur = clist_delete(fields->fld_list, cur);
1513 }
1514 break;
1515 case MAILIMF_FIELD_TO:
1516 if (single_fields->fld_to == NULL) {
1517 single_fields->fld_to = field->fld_data.fld_to;
1518 cur = clist_next(cur);
1519 }
1520 else {
1521 clist_concat(single_fields->fld_to->to_addr_list->ad_list,
1522 field->fld_data.fld_to->to_addr_list->ad_list);
1523 mailimf_field_free(field);
1524 cur = clist_delete(fields->fld_list, cur);
1525 }
1526 break;
1527 case MAILIMF_FIELD_CC:
1528 if (single_fields->fld_cc == NULL) {
1529 single_fields->fld_cc = field->fld_data.fld_cc;
1530 cur = clist_next(cur);
1531 }
1532 else {
1533 clist_concat(single_fields->fld_cc->cc_addr_list->ad_list,
1534 field->fld_data.fld_cc->cc_addr_list->ad_list);
1535 mailimf_field_free(field);
1536 cur = clist_delete(fields->fld_list, cur);
1537 }
1538 break;
1539 case MAILIMF_FIELD_BCC:
1540 if (single_fields->fld_bcc == NULL) {
1541 single_fields->fld_bcc = field->fld_data.fld_bcc;
1542 cur = clist_next(cur);
1543 }
1544 else {
1545 clist_concat(single_fields->fld_bcc->bcc_addr_list->ad_list,
1546 field->fld_data.fld_bcc->bcc_addr_list->ad_list);
1547 mailimf_field_free(field);
1548 cur = clist_delete(fields->fld_list, cur);
1549 }
1550 break;
1551 case MAILIMF_FIELD_MESSAGE_ID:
1552 if (single_fields->fld_message_id == NULL)
1553 single_fields->fld_message_id = field->fld_data.fld_message_id;
1554 cur = clist_next(cur);
1555 break;
1556 case MAILIMF_FIELD_IN_REPLY_TO:
1557 if (single_fields->fld_in_reply_to == NULL)
1558 single_fields->fld_in_reply_to = field->fld_data.fld_in_reply_to;
1559 cur = clist_next(cur);
1560 break;
1561 case MAILIMF_FIELD_REFERENCES:
1562 if (single_fields->fld_references == NULL)
1563 single_fields->fld_references = field->fld_data.fld_references;
1564 cur = clist_next(cur);
1565 break;
1566 case MAILIMF_FIELD_SUBJECT:
1567 if (single_fields->fld_subject == NULL)
1568 single_fields->fld_subject = field->fld_data.fld_subject;
1569 cur = clist_next(cur);
1570 break;
1571 case MAILIMF_FIELD_COMMENTS:
1572 if (single_fields->fld_comments == NULL)
1573 single_fields->fld_comments = field->fld_data.fld_comments;
1574 cur = clist_next(cur);
1575 break;
1576 case MAILIMF_FIELD_KEYWORDS:
1577 if (single_fields->fld_keywords == NULL)
1578 single_fields->fld_keywords = field->fld_data.fld_keywords;
1579 cur = clist_next(cur);
1580 break;
1581 default:
1582 cur = clist_next(cur);
1583 break;
1584 }
1585 }
1586}
1587
1588
1589struct mailimf_single_fields *
1590mailimf_single_fields_new(struct mailimf_fields * fields)
1591{
1592 struct mailimf_single_fields * single_fields;
1593
1594 single_fields = malloc(sizeof(struct mailimf_single_fields));
1595 if (single_fields == NULL)
1596 goto err;
1597
1598 mailimf_single_fields_init(single_fields, fields);
1599
1600 return single_fields;
1601
1602 err:
1603 return NULL;
1604}
1605
1606void mailimf_single_fields_free(struct mailimf_single_fields *
1607 single_fields)
1608{
1609 free(single_fields);
1610}
1611
1612struct mailimf_field * mailimf_field_new_custom(char * name, char * value)
1613{
1614 struct mailimf_optional_field * opt_field;
1615 struct mailimf_field * field;
1616
1617 opt_field = mailimf_optional_field_new(name, value);
1618 if (opt_field == NULL)
1619 goto err;
1620
1621 field = mailimf_field_new(MAILIMF_FIELD_OPTIONAL_FIELD,
1622 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1623 NULL, NULL, NULL, NULL,
1624 NULL, NULL, NULL, NULL,
1625 NULL, NULL, NULL, NULL,
1626 NULL, NULL, opt_field);
1627 if (field == NULL)
1628 goto free_opt_field;
1629
1630 return field;
1631
1632 free_opt_field:
1633 mailimf_optional_field_free(opt_field);
1634 err:
1635 return NULL;
1636}
diff --git a/kmicromail/libetpan/imf/mailimf_types_helper.h b/kmicromail/libetpan/imf/mailimf_types_helper.h
new file mode 100644
index 0000000..e542b4b
--- a/dev/null
+++ b/kmicromail/libetpan/imf/mailimf_types_helper.h
@@ -0,0 +1,370 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMF_TYPES_HELPER
37
38#define MAILIMF_TYPES_HELPER
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailimf_types.h>
45
46/*
47 IMPORTANT NOTE:
48
49 All allocation functions will take as argument allocated data
50 and will store these data in the structure they will allocate.
51 Data should be persistant during all the use of the structure
52 and will be freed by the free function of the structure
53
54 allocation functions will return NULL on failure
55*/
56
57/*
58 mailimf_mailbox_list_new_empty creates an empty list of mailboxes
59*/
60
61struct mailimf_mailbox_list *
62mailimf_mailbox_list_new_empty();
63
64/*
65 mailimf_mailbox_list_add adds a mailbox to the list of mailboxes
66
67 @return MAILIMF_NO_ERROR will be returned on success,
68 other code will be returned otherwise
69*/
70
71int mailimf_mailbox_list_add(struct mailimf_mailbox_list * mailbox_list,
72 struct mailimf_mailbox * mb);
73
74/*
75 mailimf_mailbox_list_add_parse parse the given string
76 into a mailimf_mailbox structure and adds it to the list of mailboxes
77
78 @return MAILIMF_NO_ERROR will be returned on success,
79 other code will be returned otherwise
80*/
81
82int mailimf_mailbox_list_add_parse(struct mailimf_mailbox_list * mailbox_list,
83 char * mb_str);
84
85/*
86 mailimf_mailbox creates a mailimf_mailbox structure with the given
87 arguments and adds it to the list of mailboxes
88
89 - display_name is the name that will be displayed for this mailbox,
90 for example 'name' in '"name" <mailbox@domain>,
91 should be allocated with malloc()
92
93 - address is the mailbox, for example 'mailbox@domain'
94 in '"name" <mailbox@domain>, should be allocated with malloc()
95
96 @return MAILIMF_NO_ERROR will be returned on success,
97 other code will be returned otherwise
98*/
99
100int mailimf_mailbox_list_add_mb(struct mailimf_mailbox_list * mailbox_list,
101 char * display_name, char * address);
102
103/*
104 mailimf_address_list_new_empty creates an empty list of addresses
105*/
106
107struct mailimf_address_list *
108mailimf_address_list_new_empty();
109
110/*
111 mailimf_address_list_add adds a mailbox to the list of addresses
112
113 @return MAILIMF_NO_ERROR will be returned on success,
114 other code will be returned otherwise
115*/
116
117int mailimf_address_list_add(struct mailimf_address_list * address_list,
118 struct mailimf_address * addr);
119
120/*
121 mailimf_address_list_add_parse parse the given string
122 into a mailimf_address structure and adds it to the list of addresses
123
124 @return MAILIMF_NO_ERROR will be returned on success,
125 other code will be returned otherwise
126*/
127
128int mailimf_address_list_add_parse(struct mailimf_address_list * address_list,
129 char * addr_str);
130
131/*
132 mailimf_address_list_add_mb creates a mailbox mailimf_address
133 with the given arguments and adds it to the list of addresses
134
135 - display_name is the name that will be displayed for this mailbox,
136 for example 'name' in '"name" <mailbox@domain>,
137 should be allocated with malloc()
138
139 - address is the mailbox, for example 'mailbox@domain'
140 in '"name" <mailbox@domain>, should be allocated with malloc()
141
142 @return MAILIMF_NO_ERROR will be returned on success,
143 other code will be returned otherwise
144*/
145
146int mailimf_address_list_add_mb(struct mailimf_address_list * address_list,
147 char * display_name, char * address);
148
149/*
150 mailimf_resent_fields_add_data adds a set of resent fields in the
151 given mailimf_fields structure.
152
153 if you don't want a given field in the set to be added in the list
154 of fields, you can give NULL as argument
155
156 @param resent_msg_id sould be allocated with malloc()
157
158 @return MAILIMF_NO_ERROR will be returned on success,
159 other code will be returned otherwise
160*/
161
162int
163mailimf_resent_fields_add_data(struct mailimf_fields * fields,
164 struct mailimf_date_time * resent_date,
165 struct mailimf_mailbox_list * resent_from,
166 struct mailimf_mailbox * resent_sender,
167 struct mailimf_address_list * resent_to,
168 struct mailimf_address_list * resent_cc,
169 struct mailimf_address_list * resent_bcc,
170 char * resent_msg_id);
171
172/*
173 mailimf_resent_fields_new_with_data_all creates a new mailimf_fields
174 structure with a set of resent fields
175
176 if you don't want a given field in the set to be added in the list
177 of fields, you can give NULL as argument
178
179 @param resent_msg_id sould be allocated with malloc()
180
181 @return MAILIMF_NO_ERROR will be returned on success,
182 other code will be returned otherwise
183*/
184
185struct mailimf_fields *
186mailimf_resent_fields_new_with_data_all(struct mailimf_date_time *
187 resent_date, struct mailimf_mailbox_list * resent_from,
188 struct mailimf_mailbox * resent_sender,
189 struct mailimf_address_list * resent_to,
190 struct mailimf_address_list * resent_cc,
191 struct mailimf_address_list * resent_bcc,
192 char * resent_msg_id);
193
194/*
195 mailimf_resent_fields_new_with_data_all creates a new mailimf_fields
196 structure with a set of resent fields.
197 Resent-Date and Resent-Message-ID fields will be generated for you.
198
199 if you don't want a given field in the set to be added in the list
200 of fields, you can give NULL as argument
201
202 @return MAILIMF_NO_ERROR will be returned on success,
203 other code will be returned otherwise
204*/
205
206struct mailimf_fields *
207mailimf_resent_fields_new_with_data(struct mailimf_mailbox_list * from,
208 struct mailimf_mailbox * sender,
209 struct mailimf_address_list * to,
210 struct mailimf_address_list * cc,
211 struct mailimf_address_list * bcc);
212
213/*
214 this function creates a new mailimf_fields structure with no fields
215*/
216
217struct mailimf_fields *
218mailimf_fields_new_empty(void);
219
220
221/*
222 this function adds a field to the mailimf_fields structure
223
224 @return MAILIMF_NO_ERROR will be returned on success,
225 other code will be returned otherwise
226*/
227
228int mailimf_fields_add(struct mailimf_fields * fields,
229 struct mailimf_field * field);
230
231
232/*
233 mailimf_fields_add_data adds a set of fields in the
234 given mailimf_fields structure.
235
236 if you don't want a given field in the set to be added in the list
237 of fields, you can give NULL as argument
238
239 @param msg_id sould be allocated with malloc()
240 @param subject should be allocated with malloc()
241 @param in_reply_to each elements of this list should be allocated
242 with malloc()
243 @param references each elements of this list should be allocated
244 with malloc()
245
246 @return MAILIMF_NO_ERROR will be returned on success,
247 other code will be returned otherwise
248*/
249
250int mailimf_fields_add_data(struct mailimf_fields * fields,
251 struct mailimf_date_time * date,
252 struct mailimf_mailbox_list * from,
253 struct mailimf_mailbox * sender,
254 struct mailimf_address_list * reply_to,
255 struct mailimf_address_list * to,
256 struct mailimf_address_list * cc,
257 struct mailimf_address_list * bcc,
258 char * msg_id,
259 clist * in_reply_to,
260 clist * references,
261 char * subject);
262
263/*
264 mailimf_fields_new_with_data_all creates a new mailimf_fields
265 structure with a set of fields
266
267 if you don't want a given field in the set to be added in the list
268 of fields, you can give NULL as argument
269
270 @param message_id sould be allocated with malloc()
271 @param subject should be allocated with malloc()
272 @param in_reply_to each elements of this list should be allocated
273 with malloc()
274 @param references each elements of this list should be allocated
275 with malloc()
276
277 @return MAILIMF_NO_ERROR will be returned on success,
278 other code will be returned otherwise
279*/
280
281struct mailimf_fields *
282mailimf_fields_new_with_data_all(struct mailimf_date_time * date,
283 struct mailimf_mailbox_list * from,
284 struct mailimf_mailbox * sender,
285 struct mailimf_address_list * reply_to,
286 struct mailimf_address_list * to,
287 struct mailimf_address_list * cc,
288 struct mailimf_address_list * bcc,
289 char * message_id,
290 clist * in_reply_to,
291 clist * references,
292 char * subject);
293
294/*
295 mailimf_fields_new_with_data creates a new mailimf_fields
296 structure with a set of fields
297 Date and Message-ID fields will be generated for you.
298
299 if you don't want a given field in the set to be added in the list
300 of fields, you can give NULL as argument
301
302 @param subject should be allocated with malloc()
303 @param in_reply_to each elements of this list should be allocated
304 with malloc()
305 @param references each elements of this list should be allocated
306 with malloc()
307
308 @return MAILIMF_NO_ERROR will be returned on success,
309 other code will be returned otherwise
310*/
311
312struct mailimf_fields *
313mailimf_fields_new_with_data(struct mailimf_mailbox_list * from,
314 struct mailimf_mailbox * sender,
315 struct mailimf_address_list * reply_to,
316 struct mailimf_address_list * to,
317 struct mailimf_address_list * cc,
318 struct mailimf_address_list * bcc,
319 clist * in_reply_to,
320 clist * references,
321 char * subject);
322
323/*
324 this function returns an allocated message identifier to
325 use in a Message-ID or Resent-Message-ID field
326*/
327
328char * mailimf_get_message_id(void);
329
330/*
331 this function returns a mailimf_date_time structure to
332 use in a Date or Resent-Date field
333*/
334
335struct mailimf_date_time * mailimf_get_current_date(void);
336
337
338/*
339 mailimf_single_fields_init fills a mailimf_single_fields structure
340 with the content of a mailimf_fields structure
341*/
342
343void mailimf_single_fields_init(struct mailimf_single_fields * single_fields,
344 struct mailimf_fields * fields);
345
346/*
347 mailimf_single_fields_new creates a new mailimf_single_fields and
348 fills the structure with mailimf_fields
349*/
350
351struct mailimf_single_fields *
352mailimf_single_fields_new(struct mailimf_fields * fields);
353
354void mailimf_single_fields_free(struct mailimf_single_fields *
355 single_fields);
356
357/*
358 mailimf_field_new_custom creates a new field of type optional
359
360 @param name should be allocated with malloc()
361 @param value should be allocated with malloc()
362*/
363
364struct mailimf_field * mailimf_field_new_custom(char * name, char * value);
365
366#ifdef __cplusplus
367}
368#endif
369
370#endif
diff --git a/kmicromail/libetpan/imf/mailimf_write.c b/kmicromail/libetpan/imf/mailimf_write.c
new file mode 100644
index 0000000..2935f7f
--- a/dev/null
+++ b/kmicromail/libetpan/imf/mailimf_write.c
@@ -0,0 +1,2021 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimf_write.h"
37
38#include <time.h>
39#include <string.h>
40#include <ctype.h>
41
42#define MAX_MAIL_COL 72
43
44#ifndef TRUE
45#define TRUE 1
46#endif
47
48#ifndef FALSE
49#define FALSE 0
50#endif
51
52#define MAX_VALID_IMF_LINE 998
53
54static int mailimf_orig_date_write(FILE * f, int * col,
55 struct mailimf_orig_date * date);
56static int mailimf_date_time_write(FILE * f, int * col,
57 struct mailimf_date_time * date_time);
58static int mailimf_from_write(FILE * f, int * col,
59 struct mailimf_from * from);
60static int mailimf_sender_write(FILE * f, int * col,
61 struct mailimf_sender * sender);
62static int mailimf_reply_to_write(FILE * f, int * col,
63 struct mailimf_reply_to * reply_to);
64static int mailimf_to_write(FILE * f, int * col,
65 struct mailimf_to * to);
66static int mailimf_cc_write(FILE * f, int * col,
67 struct mailimf_cc * to);
68static int mailimf_bcc_write(FILE * f, int * col,
69 struct mailimf_bcc * to);
70static int mailimf_message_id_write(FILE * f, int * col,
71 struct mailimf_message_id * message_id);
72static int mailimf_msg_id_list_write(FILE * f, int * col,
73 clist * list);
74static int mailimf_in_reply_to_write(FILE * f, int * col,
75 struct mailimf_in_reply_to *
76 in_reply_to);
77static int mailimf_references_write(FILE * f, int * col,
78 struct mailimf_references * references);
79static int mailimf_subject_write(FILE * f, int * col,
80 struct mailimf_subject * subject);
81
82static int mailimf_address_write(FILE * f, int * col,
83 struct mailimf_address * addr);
84static int mailimf_group_write(FILE * f, int * col,
85 struct mailimf_group * group);
86
87static int mailimf_mailbox_write(FILE * f, int * col,
88 struct mailimf_mailbox * mb);
89
90static int mailimf_comments_write(FILE * f, int * col,
91 struct mailimf_comments * comments);
92
93static int mailimf_optional_field_write(FILE * f, int * col,
94 struct mailimf_optional_field * field);
95
96static int mailimf_keywords_write(FILE * f, int * col,
97 struct mailimf_keywords * keywords);
98
99static int mailimf_return_write(FILE * f, int * col,
100 struct mailimf_return * return_path);
101
102static int mailimf_path_write(FILE * f, int * col,
103 struct mailimf_path * path);
104
105static int mailimf_resent_date_write(FILE * f, int * col,
106 struct mailimf_orig_date * date);
107
108static int mailimf_resent_from_write(FILE * f, int * col,
109 struct mailimf_from * from);
110
111static int mailimf_resent_sender_write(FILE * f, int * col,
112 struct mailimf_sender * sender);
113
114static int mailimf_resent_to_write(FILE * f, int * col,
115 struct mailimf_to * to);
116
117static int mailimf_resent_cc_write(FILE * f, int * col,
118 struct mailimf_cc * cc);
119
120static int mailimf_resent_bcc_write(FILE * f, int * col,
121 struct mailimf_bcc * bcc);
122
123static int
124mailimf_resent_msg_id_write(FILE * f, int * col,
125 struct mailimf_message_id * message_id);
126
127
128
129/* ************************ */
130
131#if 0
132int mailimf_string_write(FILE * f, int * col,
133 char * str, size_t length)
134{
135 int r;
136
137 if (length != 0) {
138 r = fwrite(str, sizeof(char), length, f);
139 if (r < 0)
140 return MAILIMF_ERROR_FILE;
141 * col += length;
142 }
143
144 return MAILIMF_NO_ERROR;
145}
146#endif
147
148#define CRLF "\r\n"
149#define HEADER_FOLD "\r\n "
150
151static inline int flush_buf(FILE * f, const char * str, size_t length)
152{
153 if (length != 0) {
154 int r;
155
156 r = fwrite(str, 1, length, f);
157 if (r == 0)
158 return MAILIMF_ERROR_FILE;
159 }
160 return MAILIMF_NO_ERROR;
161}
162
163#define CUT_AT_MAX_VALID_IMF_LINE
164
165int mailimf_string_write(FILE * f, int * col,
166 const char * str, size_t length)
167{
168 int r;
169 size_t count;
170 const char * block_begin;
171 const char * p;
172 int done;
173
174 p = str;
175 block_begin = str;
176 count = 0;
177
178 while (length > 0) {
179#ifdef CUT_AT_MAX_VALID_IMF_LINE
180 if (count >= 998) {
181 /*
182 cut lines at maximum valid length for internet message
183 format standard (currently RFC 2822)
184
185 This should not happen.
186 In case there are some lines larger than 998 in body,
187 the encoding must be changed into base64 or quoted-printable
188 so that wrapping to 72 columns is done.
189 */
190
191 r = flush_buf(f, block_begin, count);
192 if (r != MAILIMF_NO_ERROR)
193 return r;
194
195 r = fwrite(CRLF, 1, sizeof(CRLF) - 1, f);
196 if (r == 0)
197 return MAILIMF_ERROR_FILE;
198
199 count = 0;
200 block_begin = p;
201
202 * col = 0;
203 }
204#endif
205 switch (* p) {
206 case '\n':
207 r = flush_buf(f, block_begin, count);
208 if (r != MAILIMF_NO_ERROR)
209 return r;
210
211 r = fwrite(CRLF, 1, sizeof(CRLF) - 1, f);
212 if (r == 0)
213 return MAILIMF_ERROR_FILE;
214
215 p ++;
216 length --;
217 count = 0;
218 block_begin = p;
219
220 * col = 0;
221 break;
222
223 case '\r':
224 done = 0;
225 if (length >= 2) {
226 if (* (p + 1) == '\n') {
227 r = flush_buf(f, block_begin, count);
228 if (r != MAILIMF_NO_ERROR)
229 return r;
230
231 r = fwrite(CRLF, 1, sizeof(CRLF) - 1, f);
232 if (r == 0)
233 return MAILIMF_ERROR_FILE;
234
235 p += 2;
236 length -= 2;
237 count = 0;
238 block_begin = p;
239
240 * col = 0;
241
242 done = 1;
243 }
244 }
245 if (!done) {
246 r = flush_buf(f, block_begin, count);
247 if (r != MAILIMF_NO_ERROR)
248 return r;
249
250 r = fwrite(CRLF, 1, sizeof(CRLF) - 1, f);
251 if (r == 0)
252 return MAILIMF_ERROR_FILE;
253
254 p ++;
255 length --;
256 count = 0;
257 block_begin = p;
258
259 * col = 0;
260 }
261 break;
262
263 default:
264 p ++;
265 count ++;
266 length --;
267 break;
268 }
269 }
270
271 r = flush_buf(f, block_begin, count);
272 if (r != MAILIMF_NO_ERROR)
273 return r;
274 * col += count;
275
276 return MAILIMF_NO_ERROR;
277}
278
279#if 0
280int mailimf_header_string_write(FILE * f, int * col,
281 char * str, size_t length)
282{
283 char * p;
284 char * block_begin;
285 int current_col;
286 char * last_cut;
287 int r;
288 int first;
289
290 if (* col + length < MAX_MAIL_COL)
291 return mailimf_string_write(f, col, str, length);
292
293 first = 1;
294 p = str;
295 block_begin = p;
296 last_cut = block_begin;
297 current_col = * col;
298
299 while (1) {
300 if (current_col >= MAX_MAIL_COL) {
301 /* if we reach the maximum recommanded size of line */
302 if (last_cut == block_begin) {
303 /* if we could not find any place to cut */
304 if (first) {
305 /* fold the header */
306 r = mailimf_string_write(f, col, HEADER_FOLD,
307 sizeof(HEADER_FOLD) - 1);
308 if (r != MAILIMF_NO_ERROR)
309 return r;
310 current_col = * col + p - block_begin;
311 first = 0;
312 }
313 else {
314 /* cut the header */
315 r = mailimf_string_write(f, col, block_begin, p - block_begin);
316 if (r != MAILIMF_NO_ERROR)
317 return r;
318 r = mailimf_string_write(f, col, HEADER_FOLD,
319 sizeof(HEADER_FOLD) - 1);
320 if (r != MAILIMF_NO_ERROR)
321 return r;
322 first = 0;
323 block_begin = p;
324 last_cut = block_begin;
325 current_col = * col + p - block_begin;
326 }
327 }
328 else {
329 /* if we found a place to cut */
330 r = mailimf_string_write(f, col, block_begin, last_cut - block_begin);
331 if (r != MAILIMF_NO_ERROR)
332 return r;
333 r = mailimf_string_write(f, col, HEADER_FOLD,
334 sizeof(HEADER_FOLD) - 1);
335 if (r != MAILIMF_NO_ERROR)
336 return r;
337 first = 0;
338 block_begin = last_cut;
339 last_cut = block_begin;
340 current_col = * col + p - block_begin;
341 continue;
342 }
343 }
344 else {
345 if (length == 0)
346 break;
347
348 switch (* p) {
349 case ' ':
350 case '\t':
351 last_cut = p;
352 current_col ++;
353 break;
354
355 case '\r':
356 case '\n':
357 current_col = 0;
358 break;
359
360 default:
361 current_col ++;
362 break;
363 }
364
365 p ++;
366 length --;
367 }
368 }
369
370 return mailimf_string_write(f, col, block_begin, p - block_begin);
371}
372#endif
373
374#if 0
375enum {
376 STATE_LOWER_72,
377 STATE_LOWER_72_CUT,
378 STATE_EQUAL_72,
379 STATE_LOWER_998,
380 STATE_EQUAL_998,
381};
382
383int mailimf_header_string_write(FILE * f, int * col,
384 const char * str, size_t length)
385{
386 int state;
387 const char * p;
388 const char * block_begin;
389 size_t size;
390 const char * cut;
391 int r;
392
393 if (* col < MAX_MAIL_COL)
394 state = STATE_LOWER_72_CUT;
395 else if (* col == MAX_MAIL_COL)
396 state = STATE_EQUAL_72;
397 else if (* col < MAX_VALID_IMF_LINE)
398 state = STATE_LOWER_998;
399 else
400 state = STATE_EQUAL_998;
401
402 p = str;
403 block_begin = p;
404 size = * col;
405 cut = p;
406
407 while (length > 0) {
408 switch (state) {
409 case STATE_LOWER_72:
410 switch (* p) {
411 case '\r':
412 case '\n':
413 p ++;
414 length --;
415 size = 0;
416 break;
417
418 case ' ':
419 case '\t':
420 cut = p;
421 p ++;
422 length --;
423 size ++;
424 state = STATE_LOWER_72_CUT;
425 break;
426
427 default:
428 if (size < MAX_MAIL_COL - 1) {
429 p ++;
430 length --;
431 size ++;
432 }
433 else {
434 state = STATE_EQUAL_72;
435 p ++;
436 length --;
437 size ++;
438 }
439 break;
440 }
441 break; /* end of STATE_LOWER_72 */
442
443 case STATE_LOWER_72_CUT:
444 switch (* p) {
445 case '\r':
446 case '\n':
447 p ++;
448 length --;
449 size = 0;
450 state = STATE_LOWER_72;
451 break;
452
453 case ' ':
454 case '\t':
455 cut = p;
456 p ++;
457 length --;
458 size ++;
459 break;
460
461 default:
462 if (size < MAX_MAIL_COL) {
463 p ++;
464 length --;
465 size ++;
466 }
467 else {
468 r = mailimf_string_write(f, col, block_begin, cut - block_begin);
469 if (r != MAILIMF_NO_ERROR)
470 return r;
471 r = mailimf_string_write(f, col, HEADER_FOLD,
472 sizeof(HEADER_FOLD) - 1);
473 if (r != MAILIMF_NO_ERROR)
474 return r;
475 p ++;
476 length --;
477 block_begin = cut;
478 if ((* block_begin == ' ') || (* block_begin == '\t'))
479 block_begin ++;
480 size = p - block_begin + * col;
481 state = STATE_LOWER_72;
482 }
483 break;
484 }
485 break; /* end of STATE_LOWER_72_CUT */
486
487 case STATE_EQUAL_72:
488 switch (* p) {
489 case '\r':
490 case '\n':
491 p ++;
492 length --;
493 size = 0;
494 state = STATE_LOWER_72;
495 break;
496
497 case ' ':
498 case '\t':
499 r = mailimf_string_write(f, col, block_begin, p - block_begin);
500 if (r != MAILIMF_NO_ERROR)
501 return r;
502 r = mailimf_string_write(f, col, HEADER_FOLD,
503 sizeof(HEADER_FOLD) - 1);
504 if (r != MAILIMF_NO_ERROR)
505 return r;
506 p ++;
507 length --;
508 block_begin = p;
509 size = p - block_begin + * col;
510 state = STATE_LOWER_72;
511 break;
512
513 default:
514 p ++;
515 length --;
516 size ++;
517 state = STATE_LOWER_998;
518 break;
519 }
520 break; /* end of STATE_EQUAL_72 */
521
522 case STATE_LOWER_998:
523 switch (* p) {
524 case '\r':
525 case '\n':
526 p ++;
527 length --;
528 size = 0;
529 state = STATE_LOWER_72;
530 break;
531
532 case ' ':
533 case '\t':
534 r = mailimf_string_write(f, col, block_begin, p - block_begin);
535 if (r != MAILIMF_NO_ERROR)
536 return r;
537 r = mailimf_string_write(f, col, HEADER_FOLD,
538 sizeof(HEADER_FOLD) - 1);
539 if (r != MAILIMF_NO_ERROR)
540 return r;
541 p ++;
542 length --;
543 block_begin = p;
544 size = p - block_begin + * col;
545 state = STATE_LOWER_72;
546 break;
547
548 default:
549 if (size < MAX_VALID_IMF_LINE - 1) {
550 p ++;
551 length --;
552 size ++;
553 }
554 else {
555 p ++;
556 length --;
557 size = 0;
558 state = STATE_EQUAL_998;
559 }
560 break;
561 }
562 break; /* end of STATE_LOWER_998 */
563
564 case STATE_EQUAL_998:
565 switch (* p) {
566 case '\r':
567 case '\n':
568 p ++;
569 length --;
570 size = 0;
571 state = STATE_LOWER_72;
572 break;
573
574 case ' ':
575 case '\t':
576 r = mailimf_string_write(f, col, block_begin, p - block_begin);
577 if (r != MAILIMF_NO_ERROR)
578 return r;
579 r = mailimf_string_write(f, col, HEADER_FOLD,
580 sizeof(HEADER_FOLD) - 1);
581 if (r != MAILIMF_NO_ERROR)
582 return r;
583 p ++;
584 length --;
585 block_begin = p;
586 size = p - block_begin + * col;
587 state = STATE_LOWER_72;
588 break;
589
590 default:
591#ifdef CUT_AT_MAX_VALID_IMF_LINE
592 r = mailimf_string_write(f, col, block_begin, p - block_begin);
593 if (r != MAILIMF_NO_ERROR)
594 return r;
595 r = mailimf_string_write(f, col, HEADER_FOLD,
596 sizeof(HEADER_FOLD) - 1);
597 if (r != MAILIMF_NO_ERROR)
598 return r;
599 p ++;
600 length --;
601 block_begin = p;
602 size = p - block_begin + * col;
603 state = STATE_LOWER_72;
604#else
605 p ++;
606 length --;
607 size ++;
608#endif
609 break;
610 }
611 break; /* end of STATE_EQUAL_998 */
612 }
613 }
614
615 r = mailimf_string_write(f, col, block_begin, p - block_begin);
616 if (r != MAILIMF_NO_ERROR)
617 return r;
618
619 return MAILIMF_NO_ERROR;
620}
621#endif
622
623enum {
624 STATE_BEGIN,
625 STATE_WORD,
626 STATE_SPACE,
627};
628
629int mailimf_header_string_write(FILE * f, int * col,
630 const char * str, size_t length)
631{
632 int state;
633 const char * p;
634 const char * word_begin;
635 const char * word_end;
636 const char * next_word;
637 int first;
638
639 state = STATE_BEGIN;
640
641 p = str;
642 word_begin = p;
643 word_end = p;
644 next_word = p;
645 first = 1;
646
647 while (length > 0) {
648 switch (state) {
649 case STATE_BEGIN:
650 switch (* p) {
651 case '\r':
652 case '\n':
653 case ' ':
654 case '\t':
655 p ++;
656 length --;
657 break;
658
659 default:
660 word_begin = p;
661 state = STATE_WORD;
662 break;
663 }
664 break;
665
666 case STATE_SPACE:
667 switch (* p) {
668 case '\r':
669 case '\n':
670 case ' ':
671 case '\t':
672 p ++;
673 length --;
674 break;
675
676 default:
677 word_begin = p;
678 state = STATE_WORD;
679 break;
680 }
681 break;
682
683 case STATE_WORD:
684 switch (* p) {
685 case '\r':
686 case '\n':
687 case ' ':
688 case '\t':
689 if (p - word_begin + (* col) + 1 > MAX_MAIL_COL)
690 mailimf_string_write(f, col, HEADER_FOLD,
691 sizeof(HEADER_FOLD) - 1);
692 else {
693 if (!first)
694 mailimf_string_write(f, col, " ", 1);
695 }
696 first = 0;
697 mailimf_string_write(f, col, word_begin, p - word_begin);
698 state = STATE_SPACE;
699 break;
700
701 default:
702 if (p - word_begin + (* col) >= MAX_VALID_IMF_LINE) {
703 mailimf_string_write(f, col, word_begin, p - word_begin);
704 mailimf_string_write(f, col, HEADER_FOLD,
705 sizeof(HEADER_FOLD) - 1);
706 word_begin = p;
707 }
708 p ++;
709 length --;
710 break;
711 }
712 break;
713 }
714 }
715
716 if (state == STATE_WORD) {
717 if (p - word_begin + (* col) >= MAX_MAIL_COL)
718 mailimf_string_write(f, col, HEADER_FOLD,
719 sizeof(HEADER_FOLD) - 1);
720 else {
721 if (!first)
722 mailimf_string_write(f, col, " ", 1);
723 }
724 first = 0;
725 mailimf_string_write(f, col, word_begin, p - word_begin);
726 }
727
728 return MAILIMF_NO_ERROR;
729}
730
731int mailimf_envelope_fields_write(FILE * f, int * col,
732 struct mailimf_fields * fields)
733{
734 clistiter * cur;
735
736 for(cur = clist_begin(fields->fld_list) ; cur != NULL ;
737 cur = clist_next(cur)) {
738 int r;
739 struct mailimf_field * field;
740
741 field = clist_content(cur);
742 if (field->fld_type != MAILIMF_FIELD_OPTIONAL_FIELD) {
743 r = mailimf_field_write(f, col, field);
744 if (r != MAILIMF_NO_ERROR)
745 return r;
746 }
747 }
748
749 return MAILIMF_NO_ERROR;
750}
751
752int mailimf_fields_write(FILE * f, int * col,
753 struct mailimf_fields * fields)
754{
755 clistiter * cur;
756
757 for(cur = clist_begin(fields->fld_list) ; cur != NULL ;
758 cur = clist_next(cur)) {
759 int r;
760
761 r = mailimf_field_write(f, col, clist_content(cur));
762 if (r != MAILIMF_NO_ERROR)
763 return r;
764 }
765
766 return MAILIMF_NO_ERROR;
767}
768
769#if 0
770int mailimf_unparsed_fields_write(FILE * f, int * col,
771 struct mailimf_unparsed_fields * fields)
772{
773 clistiter * cur;
774
775 for(cur = clist_begin(fields->list) ; cur != NULL ; cur = cur->next) {
776 int r;
777
778 r = mailimf_optional_field_write(f, col, cur->data);
779 if (r != MAILIMF_NO_ERROR)
780 return r;
781 }
782
783 return MAILIMF_NO_ERROR;
784}
785#endif
786
787int mailimf_field_write(FILE * f, int * col,
788 struct mailimf_field * field)
789{
790 int r;
791
792 switch (field->fld_type) {
793 case MAILIMF_FIELD_RETURN_PATH:
794 r = mailimf_return_write(f, col, field->fld_data.fld_return_path);
795 break;
796 case MAILIMF_FIELD_RESENT_DATE:
797 r = mailimf_resent_date_write(f, col, field->fld_data.fld_resent_date);
798 break;
799 case MAILIMF_FIELD_RESENT_FROM:
800 r = mailimf_resent_from_write(f, col, field->fld_data.fld_resent_from);
801 break;
802 case MAILIMF_FIELD_RESENT_SENDER:
803 r = mailimf_resent_sender_write(f, col, field->fld_data.fld_resent_sender);
804 break;
805 case MAILIMF_FIELD_RESENT_TO:
806 r = mailimf_resent_to_write(f, col, field->fld_data.fld_resent_to);
807 break;
808 case MAILIMF_FIELD_RESENT_CC:
809 r = mailimf_resent_cc_write(f, col, field->fld_data.fld_resent_cc);
810 break;
811 case MAILIMF_FIELD_RESENT_BCC:
812 r = mailimf_resent_bcc_write(f, col, field->fld_data.fld_resent_bcc);
813 break;
814 case MAILIMF_FIELD_RESENT_MSG_ID:
815 r = mailimf_resent_msg_id_write(f, col, field->fld_data.fld_resent_msg_id);
816 break;
817 case MAILIMF_FIELD_ORIG_DATE:
818 r = mailimf_orig_date_write(f, col, field->fld_data.fld_orig_date);
819 break;
820 case MAILIMF_FIELD_FROM:
821 r = mailimf_from_write(f, col, field->fld_data.fld_from);
822 break;
823 case MAILIMF_FIELD_SENDER:
824 r = mailimf_sender_write(f, col, field->fld_data.fld_sender);
825 break;
826 case MAILIMF_FIELD_REPLY_TO:
827 r = mailimf_reply_to_write(f, col, field->fld_data.fld_reply_to);
828 break;
829 case MAILIMF_FIELD_TO:
830 r = mailimf_to_write(f, col, field->fld_data.fld_to);
831 break;
832 case MAILIMF_FIELD_CC:
833 r = mailimf_cc_write(f, col, field->fld_data.fld_cc);
834 break;
835 case MAILIMF_FIELD_BCC:
836 r = mailimf_bcc_write(f, col, field->fld_data.fld_bcc);
837 break;
838 case MAILIMF_FIELD_MESSAGE_ID:
839 r = mailimf_message_id_write(f, col, field->fld_data.fld_message_id);
840 break;
841 case MAILIMF_FIELD_IN_REPLY_TO:
842 r = mailimf_in_reply_to_write(f, col, field->fld_data.fld_in_reply_to);
843 break;
844 case MAILIMF_FIELD_REFERENCES:
845 r = mailimf_references_write(f, col, field->fld_data.fld_references);
846 break;
847 case MAILIMF_FIELD_SUBJECT:
848 r = mailimf_subject_write(f, col, field->fld_data.fld_subject);
849 break;
850 case MAILIMF_FIELD_COMMENTS:
851 r = mailimf_comments_write(f, col, field->fld_data.fld_comments);
852 break;
853 case MAILIMF_FIELD_KEYWORDS:
854 r = mailimf_keywords_write(f, col, field->fld_data.fld_keywords);
855 break;
856 case MAILIMF_FIELD_OPTIONAL_FIELD:
857 r = mailimf_optional_field_write(f, col, field->fld_data.fld_optional_field);
858 break;
859 default:
860 r = MAILIMF_ERROR_INVAL;
861 break;
862 }
863
864 if (r != MAILIMF_NO_ERROR)
865 return r;
866
867 return MAILIMF_NO_ERROR;
868}
869
870
871static int mailimf_orig_date_write(FILE * f, int * col,
872 struct mailimf_orig_date * date)
873{
874 int r;
875
876 r = mailimf_string_write(f, col, "Date: ", 6);
877 if (r != MAILIMF_NO_ERROR)
878 return r;
879
880 r = mailimf_date_time_write(f, col, date->dt_date_time);
881 if (r != MAILIMF_NO_ERROR)
882 return r;
883
884 r = mailimf_string_write(f, col, "\r\n", 2);
885 if (r != MAILIMF_NO_ERROR)
886 return r;
887#if 0
888 * col = 0;
889#endif
890
891 return MAILIMF_NO_ERROR;
892}
893
894#define MAX_DATE_STR 256
895
896/* 0 = Sunday */
897/* y > 1752 */
898
899static int dayofweek(int year, int month, int day)
900{
901 static int offset[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
902
903 year -= month < 3;
904
905 return (year + year/4 - year/100 + year/400 + offset[month-1] + day) % 7;
906}
907
908static const char * week_of_day_str[] = { "Sun", "Mon", "Tue", "Wed", "Thu",
909 "Fri", "Sat"};
910static const char * month_str[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
911 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
912
913static int mailimf_date_time_write(FILE * f, int * col,
914 struct mailimf_date_time * date_time)
915{
916 int r;
917 char date_str[MAX_DATE_STR];
918#if 0
919 struct tm tmval;
920 time_t timeval;
921#endif
922 int wday;
923
924#if 0
925 tmval.tm_sec = date_time->sec;
926 tmval.tm_min = date_time->min;
927 tmval.tm_hour = date_time->hour;
928 tmval.tm_sec = date_time->sec;
929 tmval.tm_mday = date_time->day;
930 tmval.tm_mon = date_time->month - 1;
931 tmval.tm_year = date_time->year - 1900;
932 tmval.tm_isdst = 1;
933
934 timeval = mktime(&tmval);
935
936 localtime_r(&timeval, &tmval);
937#endif
938
939 wday = dayofweek(date_time->dt_year, date_time->dt_month, date_time->dt_day);
940
941 snprintf(date_str, MAX_DATE_STR, "%s, %i %s %i %02i:%02i:%02i %+05i",
942 week_of_day_str[wday], date_time->dt_day,
943 month_str[date_time->dt_month - 1],
944 date_time->dt_year, date_time->dt_hour,
945 date_time->dt_min, date_time->dt_sec,
946 date_time->dt_zone);
947
948 r = mailimf_string_write(f, col, date_str, strlen(date_str));
949
950 if (r != MAILIMF_NO_ERROR)
951 return r;
952
953 return MAILIMF_NO_ERROR;
954}
955
956static int mailimf_from_write(FILE * f, int * col,
957 struct mailimf_from * from)
958{
959 int r;
960
961 r = mailimf_string_write(f, col, "From: ", 6);
962 if (r != MAILIMF_NO_ERROR)
963 return r;
964
965 r = mailimf_mailbox_list_write(f, col, from->frm_mb_list);
966 if (r != MAILIMF_NO_ERROR)
967 return r;
968
969 r = mailimf_string_write(f, col, "\r\n", 2);
970 if (r != MAILIMF_NO_ERROR)
971 return r;
972#if 0
973 * col = 0;
974#endif
975
976 return MAILIMF_NO_ERROR;
977}
978
979static int mailimf_sender_write(FILE * f, int * col,
980 struct mailimf_sender * sender)
981{
982 int r;
983
984 r = mailimf_string_write(f, col, "Sender: ", 8);
985 if (r != MAILIMF_NO_ERROR)
986 return r;
987
988 r = mailimf_mailbox_write(f, col, sender->snd_mb);
989 if (r != MAILIMF_NO_ERROR)
990 return r;
991
992 r = mailimf_string_write(f, col, "\r\n", 2);
993 if (r != MAILIMF_NO_ERROR)
994 return r;
995#if 0
996 * col = 0;
997#endif
998
999 return MAILIMF_NO_ERROR;
1000}
1001
1002static int mailimf_reply_to_write(FILE * f, int * col,
1003 struct mailimf_reply_to * reply_to)
1004{
1005 int r;
1006
1007 r = mailimf_string_write(f, col, "Reply-To: ", 10);
1008 if (r != MAILIMF_NO_ERROR)
1009 return r;
1010
1011 r = mailimf_address_list_write(f, col, reply_to->rt_addr_list);
1012 if (r != MAILIMF_NO_ERROR)
1013 return r;
1014
1015 r = mailimf_string_write(f, col, "\r\n", 2);
1016 if (r != MAILIMF_NO_ERROR)
1017 return r;
1018#if 0
1019 * col = 0;
1020#endif
1021
1022 return MAILIMF_NO_ERROR;
1023}
1024
1025
1026static int mailimf_to_write(FILE * f, int * col,
1027 struct mailimf_to * to)
1028{
1029 int r;
1030
1031 r = mailimf_string_write(f, col, "To: ", 4);
1032 if (r != MAILIMF_NO_ERROR)
1033 return r;
1034
1035 r = mailimf_address_list_write(f, col, to->to_addr_list);
1036 if (r != MAILIMF_NO_ERROR)
1037 return r;
1038
1039 r = mailimf_string_write(f, col, "\r\n", 2);
1040 if (r != MAILIMF_NO_ERROR)
1041 return r;
1042#if 0
1043 * col = 0;
1044#endif
1045
1046 return MAILIMF_NO_ERROR;
1047}
1048
1049
1050static int mailimf_cc_write(FILE * f, int * col,
1051 struct mailimf_cc * cc)
1052{
1053 int r;
1054
1055 r = mailimf_string_write(f, col, "Cc: ", 4);
1056 if (r != MAILIMF_NO_ERROR)
1057 return r;
1058
1059 r = mailimf_address_list_write(f, col, cc->cc_addr_list);
1060 if (r != MAILIMF_NO_ERROR)
1061 return r;
1062
1063 r = mailimf_string_write(f, col, "\r\n", 2);
1064 if (r != MAILIMF_NO_ERROR)
1065 return r;
1066#if 0
1067 * col = 0;
1068#endif
1069
1070 return MAILIMF_NO_ERROR;
1071}
1072
1073
1074static int mailimf_bcc_write(FILE * f, int * col,
1075 struct mailimf_bcc * bcc)
1076{
1077 int r;
1078
1079 r = mailimf_string_write(f, col, "Bcc: ", 5);
1080 if (r != MAILIMF_NO_ERROR)
1081 return r;
1082
1083 if (bcc->bcc_addr_list != NULL) {
1084 r = mailimf_address_list_write(f, col, bcc->bcc_addr_list);
1085 if (r != MAILIMF_NO_ERROR)
1086 return r;
1087 }
1088
1089 r = mailimf_string_write(f, col, "\r\n", 2);
1090 if (r != MAILIMF_NO_ERROR)
1091 return r;
1092#if 0
1093 * col = 0;
1094#endif
1095
1096 return MAILIMF_NO_ERROR;
1097}
1098
1099
1100static int mailimf_message_id_write(FILE * f, int * col,
1101 struct mailimf_message_id * message_id)
1102{
1103 int r;
1104
1105 r = mailimf_string_write(f, col, "Message-ID: ", 12);
1106 if (r != MAILIMF_NO_ERROR)
1107 return r;
1108
1109 r = mailimf_string_write(f, col, "<", 1);
1110 if (r != MAILIMF_NO_ERROR)
1111 return r;
1112
1113 r = mailimf_string_write(f, col,
1114 message_id->mid_value,
1115 strlen(message_id->mid_value));
1116 if (r != MAILIMF_NO_ERROR)
1117 return r;
1118
1119 r = mailimf_string_write(f, col, ">", 1);
1120 if (r != MAILIMF_NO_ERROR)
1121 return r;
1122
1123 r = mailimf_string_write(f, col, "\r\n", 2);
1124 if (r != MAILIMF_NO_ERROR)
1125 return r;
1126#if 0
1127 * col = 0;
1128#endif
1129
1130 return MAILIMF_NO_ERROR;
1131}
1132
1133
1134static int mailimf_msg_id_list_write(FILE * f, int * col, clist * mid_list)
1135{
1136 clistiter * cur;
1137 int r;
1138 int first;
1139
1140 first = TRUE;
1141
1142 for(cur = clist_begin(mid_list) ; cur != NULL ; cur = clist_next(cur)) {
1143 char * msgid;
1144 size_t len;
1145
1146 msgid = clist_content(cur);
1147 len = strlen(msgid);
1148
1149 /*
1150 XXX - if this is the first message ID, don't fold.
1151 This is a workaround for a bug of old versions of INN.
1152 */
1153 if (!first) {
1154 if (* col > 1) {
1155
1156 if (* col + len >= MAX_MAIL_COL) {
1157 r = mailimf_string_write(f, col, "\r\n ", 3);
1158 if (r != MAILIMF_NO_ERROR)
1159 return r;
1160#if 0
1161 * col = 1;
1162#endif
1163 first = TRUE;
1164 }
1165 }
1166 }
1167
1168 if (!first) {
1169 r = mailimf_string_write(f, col, " ", 1);
1170 if (r != MAILIMF_NO_ERROR)
1171 return r;
1172 }
1173 else {
1174 first = FALSE;
1175 }
1176
1177 r = mailimf_string_write(f, col, "<", 1);
1178 if (r != MAILIMF_NO_ERROR)
1179 return r;
1180
1181 r = mailimf_string_write(f, col, msgid, len);
1182 if (r != MAILIMF_NO_ERROR)
1183 return r;
1184
1185 r = mailimf_string_write(f, col, ">", 1);
1186 if (r != MAILIMF_NO_ERROR)
1187 return r;
1188 }
1189
1190 return MAILIMF_NO_ERROR;
1191}
1192
1193
1194static int mailimf_in_reply_to_write(FILE * f, int * col,
1195 struct mailimf_in_reply_to * in_reply_to)
1196{
1197 int r;
1198
1199 r = mailimf_string_write(f, col, "In-Reply-To: ", 13);
1200 if (r != MAILIMF_NO_ERROR)
1201 return r;
1202
1203 r = mailimf_msg_id_list_write(f, col, in_reply_to->mid_list);
1204 if (r != MAILIMF_NO_ERROR)
1205 return r;
1206
1207 r = mailimf_string_write(f, col, "\r\n", 2);
1208 if (r != MAILIMF_NO_ERROR)
1209 return r;
1210#if 0
1211 * col = 0;
1212#endif
1213
1214 return MAILIMF_NO_ERROR;
1215}
1216
1217
1218static int mailimf_references_write(FILE * f, int * col,
1219 struct mailimf_references * references)
1220{
1221 int r;
1222
1223 r = mailimf_string_write(f, col, "References: ", 12);
1224 if (r != MAILIMF_NO_ERROR)
1225 return r;
1226
1227 r = mailimf_msg_id_list_write(f, col, references->mid_list);
1228 if (r != MAILIMF_NO_ERROR)
1229 return r;
1230
1231 r = mailimf_string_write(f, col, "\r\n", 2);
1232 if (r != MAILIMF_NO_ERROR)
1233 return r;
1234#if 0
1235 * col = 0;
1236#endif
1237
1238 return MAILIMF_NO_ERROR;
1239}
1240
1241
1242
1243static int mailimf_subject_write(FILE * f, int * col,
1244 struct mailimf_subject * subject)
1245{
1246 int r;
1247
1248 r = mailimf_string_write(f, col, "Subject: ", 9);
1249 if (r != MAILIMF_NO_ERROR)
1250 return r;
1251
1252 r = mailimf_header_string_write(f, col,
1253 subject->sbj_value, strlen(subject->sbj_value));
1254 if (r != MAILIMF_NO_ERROR)
1255 return r;
1256
1257 r = mailimf_string_write(f, col, "\r\n", 2);
1258 if (r != MAILIMF_NO_ERROR)
1259 return r;
1260#if 0
1261 * col = 0;
1262#endif
1263
1264 return MAILIMF_NO_ERROR;
1265}
1266
1267int mailimf_address_list_write(FILE * f, int * col,
1268 struct mailimf_address_list * addr_list)
1269{
1270 clistiter * cur;
1271 int r;
1272 int first;
1273
1274 first = TRUE;
1275
1276 for(cur = clist_begin(addr_list->ad_list) ; cur != NULL ;
1277 cur = clist_next(cur)) {
1278 struct mailimf_address * addr;
1279
1280 addr = clist_content(cur);
1281
1282 if (!first) {
1283 r = mailimf_string_write(f, col, ", ", 2);
1284 if (r != MAILIMF_NO_ERROR)
1285 return r;
1286 }
1287 else {
1288 first = FALSE;
1289 }
1290
1291 r = mailimf_address_write(f, col, addr);
1292 if (r != MAILIMF_NO_ERROR)
1293 return r;
1294 }
1295
1296 return MAILIMF_NO_ERROR;
1297}
1298
1299
1300static int mailimf_address_write(FILE * f, int * col,
1301 struct mailimf_address * addr)
1302{
1303 int r;
1304
1305 switch(addr->ad_type) {
1306 case MAILIMF_ADDRESS_MAILBOX:
1307 r = mailimf_mailbox_write(f, col, addr->ad_data.ad_mailbox);
1308 if (r != MAILIMF_NO_ERROR)
1309 return r;
1310
1311 break;
1312
1313 case MAILIMF_ADDRESS_GROUP:
1314 r = mailimf_group_write(f, col, addr->ad_data.ad_group);
1315 if (r != MAILIMF_NO_ERROR)
1316 return r;
1317
1318 break;
1319 }
1320
1321 return MAILIMF_NO_ERROR;
1322}
1323
1324
1325static int mailimf_group_write(FILE * f, int * col,
1326 struct mailimf_group * group)
1327{
1328 int r;
1329
1330 r = mailimf_header_string_write(f, col, group->grp_display_name,
1331 strlen(group->grp_display_name));
1332 if (r != MAILIMF_NO_ERROR)
1333 return r;
1334
1335 r = mailimf_string_write(f, col, ": ", 2);
1336 if (r != MAILIMF_NO_ERROR)
1337 return r;
1338
1339 if (group->grp_mb_list != NULL) {
1340 r = mailimf_mailbox_list_write(f, col, group->grp_mb_list);
1341 if (r != MAILIMF_NO_ERROR)
1342 return r;
1343 }
1344
1345 r = mailimf_string_write(f, col, ";", 1);
1346 if (r != MAILIMF_NO_ERROR)
1347 return r;
1348
1349 return MAILIMF_NO_ERROR;
1350}
1351
1352
1353int mailimf_mailbox_list_write(FILE * f, int * col,
1354 struct mailimf_mailbox_list * mb_list)
1355{
1356 clistiter * cur;
1357 int r;
1358 int first;
1359
1360 first = TRUE;
1361
1362 for(cur = clist_begin(mb_list->mb_list) ; cur != NULL ;
1363 cur = clist_next(cur)) {
1364 struct mailimf_mailbox * mb;
1365
1366 mb = clist_content(cur);
1367
1368 if (!first) {
1369 r = mailimf_string_write(f, col, ", ", 2);
1370 if (r != MAILIMF_NO_ERROR)
1371 return r;
1372 }
1373 else {
1374 first = FALSE;
1375 }
1376
1377 r = mailimf_mailbox_write(f, col, mb);
1378 if (r != MAILIMF_NO_ERROR)
1379 return r;
1380 }
1381
1382 return MAILIMF_NO_ERROR;
1383}
1384
1385
1386int mailimf_quoted_string_write(FILE * f, int * col,
1387 const char * string, size_t len)
1388{
1389 int r;
1390 size_t i;
1391
1392 fputc('\"', f);
1393 for(i = 0 ; i < len ; i ++) {
1394 switch (string[i]) {
1395 case '\\':
1396 case '\"':
1397 r = fputc('\\', f);
1398 if (r < 0)
1399 return MAILIMF_ERROR_FILE;
1400 r = fputc(string[i], f);
1401 if (r < 0)
1402 return MAILIMF_ERROR_FILE;
1403 (* col) += 2;
1404 break;
1405
1406 default:
1407 r = fputc(string[i], f);
1408 if (r < 0)
1409 return MAILIMF_ERROR_FILE;
1410 (* col) ++;
1411 break;
1412 }
1413 }
1414 fputc('\"', f);
1415
1416 return MAILIMF_NO_ERROR;
1417}
1418
1419
1420/*
1421static int
1422atext = ALPHA / DIGIT / ; Any character except controls,
1423 "!" / "#" / ; SP, and specials.
1424 "$" / "%" / ; Used for atoms
1425 "&" / "'" /
1426 "*" / "+" /
1427 "-" / "/" /
1428 "=" / "?" /
1429 "^" / "_" /
1430 "`" / "{" /
1431 "|" / "}" /
1432 "~"
1433*/
1434
1435static int is_atext(const char * s)
1436{
1437 const char * p;
1438
1439 for(p = s ; * p != 0 ; p ++) {
1440 if (isalpha((unsigned char) * p))
1441 continue;
1442 if (isdigit((unsigned char) * p))
1443 continue;
1444 switch (*p) {
1445 case ' ':
1446 case '\t':
1447 case '!':
1448 case '#':
1449 case '$':
1450 case '%':
1451 case '&':
1452 case '\'':
1453 case '*':
1454 case '+':
1455 case '-':
1456 case '/':
1457 case '=':
1458 case '?':
1459 case '^':
1460 case '_':
1461 case '`':
1462 case '{':
1463 case '|':
1464 case '}':
1465 case '~':
1466 break;
1467 default:
1468 return 0;
1469 }
1470 }
1471
1472 return 1;
1473}
1474
1475static int mailimf_mailbox_write(FILE * f, int * col,
1476 struct mailimf_mailbox * mb)
1477{
1478 int r;
1479 int do_fold;
1480
1481#if 0
1482 if (* col > 1) {
1483
1484 if (mb->mb_display_name != NULL) {
1485 if (* col + strlen(mb->mb_display_name) >= MAX_MAIL_COL) {
1486 r = mailimf_string_write(f, col, "\r\n ", 3);
1487 if (r != MAILIMF_NO_ERROR)
1488 return r;
1489#if 0
1490 * col = 1;
1491#endif
1492 }
1493 }
1494 }
1495#endif
1496
1497 if (mb->mb_display_name) {
1498
1499 if (is_atext(mb->mb_display_name)) {
1500 r = mailimf_header_string_write(f, col, mb->mb_display_name,
1501 strlen(mb->mb_display_name));
1502 if (r != MAILIMF_NO_ERROR)
1503 return r;
1504 }
1505 else {
1506 if (mb->mb_display_name != NULL) {
1507 if (* col + strlen(mb->mb_display_name) >= MAX_MAIL_COL) {
1508 r = mailimf_string_write(f, col, "\r\n ", 3);
1509 if (r != MAILIMF_NO_ERROR)
1510 return r;
1511 }
1512 }
1513
1514 if (strlen(mb->mb_display_name) > MAX_VALID_IMF_LINE / 2)
1515 return MAILIMF_ERROR_INVAL;
1516
1517 r = mailimf_quoted_string_write(f, col, mb->mb_display_name,
1518 strlen(mb->mb_display_name));
1519 if (r != MAILIMF_NO_ERROR)
1520 return r;
1521 }
1522
1523 do_fold = 0;
1524 if (* col > 1) {
1525
1526 if (* col + strlen(mb->mb_addr_spec) + 3 >= MAX_MAIL_COL) {
1527 r = mailimf_string_write(f, col, "\r\n ", 3);
1528 if (r != MAILIMF_NO_ERROR)
1529 return r;
1530#if 0
1531 * col = 1;
1532#endif
1533 do_fold = 1;
1534 }
1535 }
1536
1537 if (do_fold)
1538 r = mailimf_string_write(f, col, "<", 1);
1539 else
1540 r = mailimf_string_write(f, col, " <", 2);
1541 if (r != MAILIMF_NO_ERROR)
1542 return r;
1543
1544 r = mailimf_string_write(f, col, mb->mb_addr_spec,
1545 strlen(mb->mb_addr_spec));
1546 if (r != MAILIMF_NO_ERROR)
1547 return r;
1548
1549 r = mailimf_string_write(f, col, ">", 1);
1550 if (r != MAILIMF_NO_ERROR)
1551 return r;
1552 }
1553 else {
1554 if (* col + strlen(mb->mb_addr_spec) >= MAX_MAIL_COL) {
1555 r = mailimf_string_write(f, col, "\r\n ", 3);
1556 if (r != MAILIMF_NO_ERROR)
1557 return r;
1558 }
1559
1560 r = mailimf_string_write(f, col,
1561 mb->mb_addr_spec, strlen(mb->mb_addr_spec));
1562 if (r != MAILIMF_NO_ERROR)
1563 return r;
1564 }
1565
1566
1567 return MAILIMF_NO_ERROR;
1568}
1569
1570static int mailimf_comments_write(FILE * f, int * col,
1571 struct mailimf_comments * comments)
1572{
1573 int r;
1574
1575 r = mailimf_string_write(f, col, "Comments: ", 10);
1576 if (r != MAILIMF_NO_ERROR)
1577 return r;
1578
1579 r = mailimf_header_string_write(f, col,
1580 comments->cm_value, strlen(comments->cm_value));
1581 if (r != MAILIMF_NO_ERROR)
1582 return r;
1583
1584 r = mailimf_string_write(f, col, "\r\n", 2);
1585 if (r != MAILIMF_NO_ERROR)
1586 return r;
1587#if 0
1588 * col = 0;
1589#endif
1590
1591 return MAILIMF_NO_ERROR;
1592}
1593
1594static int mailimf_optional_field_write(FILE * f, int * col,
1595 struct mailimf_optional_field * field)
1596{
1597 int r;
1598
1599 if (strlen(field->fld_name) + 2 > MAX_VALID_IMF_LINE)
1600 return MAILIMF_ERROR_INVAL;
1601
1602 r = mailimf_string_write(f, col, field->fld_name, strlen(field->fld_name));
1603 if (r != MAILIMF_NO_ERROR)
1604 return r;
1605
1606 r = mailimf_string_write(f, col, ": ", 2);
1607 if (r != MAILIMF_NO_ERROR)
1608 return r;
1609
1610 r = mailimf_header_string_write(f, col, field->fld_value,
1611 strlen(field->fld_value));
1612 if (r != MAILIMF_NO_ERROR)
1613 return r;
1614
1615#if 0
1616 /* XXX parsing debug */
1617 mailimf_string_write(f, col, " (X)", 4);
1618#endif
1619
1620 r = mailimf_string_write(f, col, "\r\n", 2);
1621 if (r != MAILIMF_NO_ERROR)
1622 return r;
1623#if 0
1624 * col = 0;
1625#endif
1626
1627 return MAILIMF_NO_ERROR;
1628}
1629
1630static int mailimf_keywords_write(FILE * f, int * col,
1631 struct mailimf_keywords * keywords)
1632{
1633 int r;
1634 clistiter * cur;
1635 int first;
1636
1637 r = mailimf_string_write(f, col, "Keywords: ", 10);
1638 if (r != MAILIMF_NO_ERROR)
1639 return r;
1640
1641 first = TRUE;
1642
1643 for(cur = clist_begin(keywords->kw_list) ; cur != NULL ;
1644 cur = clist_next(cur)) {
1645 char * keyword;
1646 size_t len;
1647
1648 keyword = clist_content(cur);
1649 len = strlen(keyword);
1650
1651 if (!first) {
1652 r = mailimf_string_write(f, col, ", ", 2);
1653 if (r != MAILIMF_NO_ERROR)
1654 return r;
1655 }
1656 else {
1657 first = FALSE;
1658 }
1659
1660#if 0
1661 if (* col > 1) {
1662
1663 if (* col + len >= MAX_MAIL_COL) {
1664 r = mailimf_string_write(f, col, "\r\n ", 3);
1665 if (r != MAILIMF_NO_ERROR)
1666 return r;
1667#if 0
1668 * col = 1;
1669#endif
1670 }
1671 }
1672#endif
1673
1674 r = mailimf_header_string_write(f, col, keyword, len);
1675 if (r != MAILIMF_NO_ERROR)
1676 return r;
1677 }
1678
1679 r = mailimf_string_write(f, col, "\r\n", 2);
1680 if (r != MAILIMF_NO_ERROR)
1681 return r;
1682#if 0
1683 * col = 0;
1684#endif
1685
1686 return MAILIMF_NO_ERROR;
1687}
1688
1689#if 0
1690static int mailimf_delivering_info_write(FILE * f, int * col,
1691 struct mailimf_delivering_info * info)
1692{
1693 clistiter * cur;
1694 int r;
1695
1696 for(cur = clist_begin(info->received_fields) ;
1697 cur != NULL ; cur = cur->next) {
1698 struct mailimf_trace_resent_fields * field;
1699
1700 field = cur->data;
1701
1702 r = mailimf_trace_resent_fields_write(f, col, field);
1703 if (r != MAILIMF_NO_ERROR)
1704 return r;
1705 }
1706
1707 return MAILIMF_NO_ERROR;
1708}
1709
1710
1711static int
1712mailimf_trace_resent_fields_write(FILE * f, int * col,
1713 struct mailimf_trace_resent_fields * field)
1714{
1715 int r;
1716
1717 if (field->return_path != NULL) {
1718 r = mailimf_return_write(f, col, field->return_path);
1719 if (r != MAILIMF_NO_ERROR)
1720 return r;
1721 }
1722
1723 if (field->resent_fields != NULL) {
1724 r = mailimf_resent_fields_write(f, col, field->resent_fields);
1725 if (r != MAILIMF_NO_ERROR)
1726 return r;
1727 }
1728
1729 return MAILIMF_NO_ERROR;
1730}
1731#endif
1732
1733static int mailimf_return_write(FILE * f, int * col,
1734 struct mailimf_return * return_path)
1735{
1736 int r;
1737
1738 r = mailimf_string_write(f, col, "Return-Path: ", 13);
1739 if (r != MAILIMF_NO_ERROR)
1740 return r;
1741
1742 r = mailimf_path_write(f, col, return_path->ret_path);
1743 if (r != MAILIMF_NO_ERROR)
1744 return r;
1745
1746 r = mailimf_string_write(f, col, "\r\n", 2);
1747 if (r != MAILIMF_NO_ERROR)
1748 return r;
1749#if 0
1750 * col = 0;
1751#endif
1752
1753 return MAILIMF_NO_ERROR;
1754}
1755
1756static int mailimf_path_write(FILE * f, int * col,
1757 struct mailimf_path * path)
1758{
1759 int r;
1760
1761 r = mailimf_string_write(f, col, "<", 1);
1762 if (r != MAILIMF_NO_ERROR)
1763 return r;
1764
1765 r = mailimf_string_write(f, col, path->pt_addr_spec,
1766 strlen(path->pt_addr_spec));
1767 if (r != MAILIMF_NO_ERROR)
1768 return r;
1769
1770 r = mailimf_string_write(f, col, ">", 1);
1771 if (r != MAILIMF_NO_ERROR)
1772 return r;
1773
1774 return MAILIMF_NO_ERROR;
1775}
1776
1777#if 0
1778static int mailimf_resent_fields_write(FILE * f, int * col,
1779 struct mailimf_resent_fields_list *
1780 resent_fields)
1781{
1782 clistiter * cur;
1783 int r;
1784
1785 for(cur = clist_begin(resent_fields->list) ; cur != NULL ; cur = cur->next) {
1786 struct mailimf_resent_field * field;
1787
1788 field = cur->data;
1789
1790 r = mailimf_resent_field_write(f, col, field);
1791 if (r != MAILIMF_NO_ERROR)
1792 return r;
1793 }
1794
1795 return MAILIMF_NO_ERROR;
1796}
1797
1798
1799
1800static int mailimf_resent_field_write(FILE * f, int * col,
1801 struct mailimf_resent_field *
1802 resent_field)
1803{
1804 int r;
1805
1806 switch (resent_field->type) {
1807 case MAILIMF_RESENT_FIELD_DATE:
1808 r = mailimf_resent_date_write(f, col, resent_field->resent_date);
1809 break;
1810
1811 case MAILIMF_RESENT_FIELD_FROM:
1812 r = mailimf_resent_from_write(f, col, resent_field->resent_from);
1813 break;
1814
1815 case MAILIMF_RESENT_FIELD_SENDER:
1816 r = mailimf_resent_sender_write(f, col, resent_field->resent_sender);
1817 break;
1818
1819 case MAILIMF_RESENT_FIELD_TO:
1820 r = mailimf_resent_to_write(f, col, resent_field->resent_to);
1821 break;
1822
1823 case MAILIMF_RESENT_FIELD_CC:
1824 r = mailimf_resent_cc_write(f, col, resent_field->resent_cc);
1825 break;
1826
1827 case MAILIMF_RESENT_FIELD_BCC:
1828 r = mailimf_resent_bcc_write(f, col, resent_field->resent_bcc);
1829 break;
1830
1831 case MAILIMF_RESENT_FIELD_MSG_ID:
1832 r = mailimf_resent_msg_id_write(f, col, resent_field->resent_msg_id);
1833 break;
1834 default:
1835 r = MAILIMF_ERROR_INVAL;
1836 break;
1837 }
1838
1839
1840 if (r != MAILIMF_NO_ERROR)
1841 return r;
1842
1843 return MAILIMF_NO_ERROR;
1844}
1845#endif
1846
1847static int mailimf_resent_date_write(FILE * f, int * col,
1848 struct mailimf_orig_date * date)
1849{
1850 int r;
1851
1852 r = mailimf_string_write(f, col, "Resent-Date: ", 13);
1853 if (r != MAILIMF_NO_ERROR)
1854 return r;
1855
1856 r = mailimf_date_time_write(f, col, date->dt_date_time);
1857 if (r != MAILIMF_NO_ERROR)
1858 return r;
1859
1860 r = mailimf_string_write(f, col, "\r\n", 2);
1861 if (r != MAILIMF_NO_ERROR)
1862 return r;
1863#if 0
1864 * col = 0;
1865#endif
1866
1867 return MAILIMF_NO_ERROR;
1868}
1869
1870static int mailimf_resent_from_write(FILE * f, int * col,
1871 struct mailimf_from * from)
1872{
1873 int r;
1874
1875 r = mailimf_string_write(f, col, "Resent-From: ", 13);
1876 if (r != MAILIMF_NO_ERROR)
1877 return r;
1878
1879 r = mailimf_mailbox_list_write(f, col, from->frm_mb_list);
1880 if (r != MAILIMF_NO_ERROR)
1881 return r;
1882
1883 r = mailimf_string_write(f, col, "\r\n", 2);
1884 if (r != MAILIMF_NO_ERROR)
1885 return r;
1886#if 0
1887 * col = 0;
1888#endif
1889
1890 return MAILIMF_NO_ERROR;
1891}
1892
1893static int mailimf_resent_sender_write(FILE * f, int * col,
1894 struct mailimf_sender * sender)
1895{
1896 int r;
1897
1898 r = mailimf_string_write(f, col, "Resent-Sender: ", 15);
1899 if (r != MAILIMF_NO_ERROR)
1900 return r;
1901
1902 r = mailimf_mailbox_write(f, col, sender->snd_mb);
1903 if (r != MAILIMF_NO_ERROR)
1904 return r;
1905
1906 r = mailimf_string_write(f, col, "\r\n", 2);
1907 if (r != MAILIMF_NO_ERROR)
1908 return r;
1909#if 0
1910 * col = 0;
1911#endif
1912
1913 return MAILIMF_NO_ERROR;
1914}
1915
1916static int mailimf_resent_to_write(FILE * f, int * col,
1917 struct mailimf_to * to)
1918{
1919 int r;
1920
1921 r = mailimf_string_write(f, col, "Resent-To: ", 11);
1922 if (r != MAILIMF_NO_ERROR)
1923 return r;
1924
1925 r = mailimf_address_list_write(f, col, to->to_addr_list);
1926 if (r != MAILIMF_NO_ERROR)
1927 return r;
1928
1929 r = mailimf_string_write(f, col, "\r\n", 2);
1930 if (r != MAILIMF_NO_ERROR)
1931 return r;
1932#if 0
1933 * col = 0;
1934#endif
1935
1936 return MAILIMF_NO_ERROR;
1937}
1938
1939
1940static int mailimf_resent_cc_write(FILE * f, int * col,
1941 struct mailimf_cc * cc)
1942{
1943 int r;
1944
1945 r = mailimf_string_write(f, col, "Resent-Cc: ", 11);
1946 if (r != MAILIMF_NO_ERROR)
1947 return r;
1948
1949 r = mailimf_address_list_write(f, col, cc->cc_addr_list);
1950 if (r != MAILIMF_NO_ERROR)
1951 return r;
1952
1953 r = mailimf_string_write(f, col, "\r\n", 2);
1954 if (r != MAILIMF_NO_ERROR)
1955 return r;
1956#if 0
1957 * col = 0;
1958#endif
1959
1960 return MAILIMF_NO_ERROR;
1961}
1962
1963
1964static int mailimf_resent_bcc_write(FILE * f, int * col,
1965 struct mailimf_bcc * bcc)
1966{
1967 int r;
1968
1969 r = mailimf_string_write(f, col, "Resent-Bcc: ", 12);
1970 if (r != MAILIMF_NO_ERROR)
1971 return r;
1972
1973 if (bcc->bcc_addr_list != NULL) {
1974 r = mailimf_address_list_write(f, col, bcc->bcc_addr_list);
1975 if (r != MAILIMF_NO_ERROR)
1976 return r;
1977 }
1978
1979 r = mailimf_string_write(f, col, "\r\n", 2);
1980 if (r != MAILIMF_NO_ERROR)
1981 return r;
1982#if 0
1983 * col = 0;
1984#endif
1985
1986 return MAILIMF_NO_ERROR;
1987}
1988
1989
1990static int
1991mailimf_resent_msg_id_write(FILE * f, int * col,
1992 struct mailimf_message_id * message_id)
1993{
1994 int r;
1995
1996 r = mailimf_string_write(f, col, "Resent-Message-ID: ", 19);
1997 if (r != MAILIMF_NO_ERROR)
1998 return r;
1999
2000 r = mailimf_string_write(f, col, "<", 1);
2001 if (r != MAILIMF_NO_ERROR)
2002 return r;
2003
2004 r = mailimf_string_write(f, col,
2005 message_id->mid_value, strlen(message_id->mid_value));
2006 if (r != MAILIMF_NO_ERROR)
2007 return r;
2008
2009 r = mailimf_string_write(f, col, ">", 1);
2010 if (r != MAILIMF_NO_ERROR)
2011 return r;
2012
2013 r = mailimf_string_write(f, col, "\r\n", 2);
2014 if (r != MAILIMF_NO_ERROR)
2015 return r;
2016#if 0
2017 * col = 0;
2018#endif
2019
2020 return MAILIMF_NO_ERROR;
2021}
diff --git a/kmicromail/libetpan/imf/mailimf_write.h b/kmicromail/libetpan/imf/mailimf_write.h
new file mode 100644
index 0000000..b3e61ab
--- a/dev/null
+++ b/kmicromail/libetpan/imf/mailimf_write.h
@@ -0,0 +1,134 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMF_WRITE_H
37
38#define MAILIMF_WRITE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <stdio.h>
45#include <libetpan/mailimf_types.h>
46
47/*
48 mailimf_string_write writes a string to a given stream
49
50 @param f is the stream
51 @param col (* col) is the column number where we will start to
52 write the text, the ending column will be stored in (* col)
53 @param str is the string to write
54*/
55
56int mailimf_string_write(FILE * f, int * col,
57 const char * str, size_t length);
58
59
60/*
61 mailimf_fields_write writes the fields to a given stream
62
63 @param f is the stream
64 @param col (* col) is the column number where we will start to
65 write the text, the ending column will be stored in (* col)
66 @param fields is the fields to write
67*/
68
69int mailimf_fields_write(FILE * f, int * col,
70 struct mailimf_fields * fields);
71
72
73/*
74 mailimf_envelope_fields_write writes only some fields to a given stream
75
76 @param f is the stream
77 @param col (* col) is the column number where we will start to
78 write the text, the ending column will be stored in (* col)
79 @param fields is the fields to write
80*/
81
82int mailimf_envelope_fields_write(FILE * f, int * col,
83 struct mailimf_fields * fields);
84
85
86/*
87 mailimf_field_write writes a field to a given stream
88
89 @param f is the stream
90 @param col (* col) is the column number where we will start to
91 write the text, the ending column will be stored in (* col)
92 @param field is the field to write
93*/
94
95int mailimf_field_write(FILE * f, int * col,
96 struct mailimf_field * field);
97
98/*
99 mailimf_quoted_string_write writes a string that is quoted
100 to a given stream
101
102 @param f is the stream
103 @param col (* col) is the column number where we will start to
104 write the text, the ending column will be stored in (* col)
105 @param string is the string to quote and write
106*/
107
108int mailimf_quoted_string_write(FILE * f, int * col,
109 const char * string, size_t len);
110
111int mailimf_address_list_write(FILE * f, int * col,
112 struct mailimf_address_list * addr_list);
113
114int mailimf_mailbox_list_write(FILE * f, int * col,
115 struct mailimf_mailbox_list * mb_list);
116
117/*
118 mailimf_header_string_write writes a header value and fold the header
119 if needed.
120
121 @param f is the stream
122 @param col (* col) is the column number where we will start to
123 write the text, the ending column will be stored in (* col)
124 @param str is the string to write
125*/
126
127int mailimf_header_string_write(FILE * f, int * col,
128 const char * str, size_t length);
129
130#ifdef __cplusplus
131}
132#endif
133
134#endif
diff --git a/kmicromail/libetpan/include/libetpan/carray.h b/kmicromail/libetpan/include/libetpan/carray.h
new file mode 100644
index 0000000..06003aa
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/carray.h
@@ -0,0 +1,124 @@
1
2/*
3 * libEtPan! -- a mail stuff library
4 *
5 * carray - Implements simple dynamic pointer arrays
6 *
7 * Copyright (c) 1999-2000, Gaël Roualland <gael.roualland@iname.com>
8 * interface changes - 2002 - DINH Viet Hoa
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the libEtPan! project nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36/*
37 * $Id$
38 */
39
40#ifndef CARRAY_H
41#define CARRAY_H
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47struct carray_s {
48 void ** array;
49 unsigned int len;
50 unsigned int max;
51};
52
53typedef struct carray_s carray;
54
55/* Creates a new array of pointers, with initsize preallocated cells */
56carray * carray_new(unsigned int initsize);
57
58/* Adds the pointer to data in the array.
59 Returns the index of the pointer in the array or -1 on error */
60int carray_add(carray * array, void * data, unsigned int * index);
61
62int carray_set_size(carray * array, unsigned int new_size);
63
64/* Removes the cell at this index position. Returns TRUE on success.
65 Order of elements in the array IS changed. */
66int carray_delete(carray * array, unsigned int indx);
67
68/* Removes the cell at this index position. Returns TRUE on success.
69 Order of elements in the array IS not changed. */
70int carray_delete_slow(carray * array, unsigned int indx);
71
72/* remove without decreasing the size of the array */
73int carray_delete_fast(carray * array, unsigned int indx);
74
75/* Some of the following routines can be implemented as macros to
76 be faster. If you don't want it, define NO_MACROS */
77#ifdef NO_MACROS
78
79/* Returns the array itself */
80void ** carray_data(carray *);
81
82/* Returns the number of elements in the array */
83int carray_count(carray *);
84
85/* Returns the contents of one cell */
86void * carray_get(carray * array, unsigned int indx);
87
88/* Sets the contents of one cell */
89void carray_set(carray * array, unsigned int indx, void * value);
90
91#else
92
93#if 0
94#define carray_data(a) (a->array)
95#define carray_count(a) (a->len)
96#define carray_get(a, indx) (a->array[indx])
97#define carray_set(a, indx, v) do { a->array[indx]=v; } while(0)
98#endif
99
100static inline void ** carray_data(carray * array) {
101 return array->array;
102}
103
104static inline unsigned int carray_count(carray * array) {
105 return array->len;
106}
107
108static inline void * carray_get(carray * array, unsigned int indx) {
109 return array->array[indx];
110}
111
112static inline void carray_set(carray * array,
113 unsigned int indx, void * value) {
114 array->array[indx] = value;
115}
116#endif
117
118void carray_free(carray * array);
119
120#ifdef __cplusplus
121}
122#endif
123
124#endif
diff --git a/kmicromail/libetpan/include/libetpan/charconv.h b/kmicromail/libetpan/include/libetpan/charconv.h
new file mode 100644
index 0000000..5a435ff
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/charconv.h
@@ -0,0 +1,67 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef CHARCONV_H
37
38#define CHARCONV_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <sys/types.h>
45
46enum {
47 MAIL_CHARCONV_NO_ERROR = 0,
48 MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET,
49 MAIL_CHARCONV_ERROR_MEMORY,
50 MAIL_CHARCONV_ERROR_CONV,
51};
52
53int charconv(const char * tocode, const char * fromcode,
54 const char * str, size_t length,
55 char ** result);
56
57int charconv_buffer(const char * tocode, const char * fromcode,
58 const char * str, size_t length,
59 char ** result, size_t * result_len);
60
61void charconv_buffer_free(char * str);
62
63#ifdef __cplusplus
64}
65#endif
66
67#endif
diff --git a/kmicromail/libetpan/include/libetpan/chash.h b/kmicromail/libetpan/include/libetpan/chash.h
new file mode 100644
index 0000000..3b2b7d3
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/chash.h
@@ -0,0 +1,166 @@
1
2/*
3 * libEtPan! -- a mail stuff library
4 *
5 * chash - Implements generic hash tables.
6 *
7 * Copyright (c) 1999-2000, Gaël Roualland <gael.roualland@iname.com>
8 * interface changes - 2002 - DINH Viet Hoa
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the libEtPan! project nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36/*
37 * $Id$
38 */
39
40#ifndef CHASH_H
41#define CHASH_H
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47typedef struct {
48 void * data;
49 unsigned int len;
50} chashdatum;
51
52struct chash {
53 unsigned int size;
54 unsigned int count;
55 int copyvalue;
56 int copykey;
57 struct chashcell ** cells;
58};
59
60typedef struct chash chash;
61
62struct chashcell {
63 unsigned int func;
64 chashdatum key;
65 chashdatum value;
66 struct chashcell * next;
67};
68
69typedef struct chashcell chashiter;
70
71#define CHASH_COPYNONE 0
72#define CHASH_COPYKEY 1
73#define CHASH_COPYVALUE 2
74#define CHASH_COPYALL (CHASH_COPYKEY | CHASH_COPYVALUE)
75
76#define CHASH_DEFAULTSIZE 13
77
78/* Allocates a new (empty) hash using this initial size and the given flags,
79 specifying which data should be copied in the hash.
80 CHASH_COPYNONE : Keys/Values are not copied.
81 CHASH_COPYKEY : Keys are dupped and freed as needed in the hash.
82 CHASH_COPYVALUE : Values are dupped and freed as needed in the hash.
83 CHASH_COPYALL : Both keys and values are dupped in the hash.
84 */
85chash * chash_new(unsigned int size, int flags);
86
87/* Frees a hash */
88void chash_free(chash * hash);
89
90/* Removes all elements from a hash */
91void chash_clear(chash * hash);
92
93/* Adds an entry in the hash table.
94 Length can be 0 if key/value are strings.
95 If an entry already exists for this key, it is replaced, and its value
96 is returned. Otherwise, the data pointer will be NULL and the length
97 field be set to TRUE or FALSe to indicate success or failure. */
98int chash_set(chash * hash,
99 chashdatum * key,
100 chashdatum * value,
101 chashdatum * oldvalue);
102
103/* Retrieves the data associated to the key if it is found in the hash table.
104 The data pointer and the length will be NULL if not found*/
105int chash_get(chash * hash,
106 chashdatum * key, chashdatum * result);
107
108/* Removes the entry associated to this key if it is found in the hash table,
109 and returns its contents if not dupped (otherwise, pointer will be NULL
110 and len TRUE). If entry is not found both pointer and len will be NULL. */
111int chash_delete(chash * hash,
112 chashdatum * key,
113 chashdatum * oldvalue);
114
115/* Resizes the hash table to the passed size. */
116int chash_resize(chash * hash, unsigned int size);
117
118/* Returns an iterator to the first non-empty entry of the hash table */
119chashiter * chash_begin(chash * hash);
120
121/* Returns the next non-empty entry of the hash table */
122chashiter * chash_next(chash * hash, chashiter * iter);
123
124/* Some of the following routines can be implemented as macros to
125 be faster. If you don't want it, define NO_MACROS */
126#ifdef NO_MACROS
127/* Returns the size of the hash table */
128unsigned int chash_size(chash * hash);
129
130/* Returns the number of entries in the hash table */
131unsigned int chash_count(chash * hash);
132
133/* Returns the key part of the entry pointed by the iterator */
134void chash_key(chashiter * iter, chashdatum * result);
135
136/* Returns the value part of the entry pointed by the iterator */
137void chash_value(chashiter * iter, chashdatum * result);
138
139#else
140static inline unsigned int chash_size(chash * hash)
141{
142 return hash->size;
143}
144
145static inline unsigned int chash_count(chash * hash)
146{
147 return hash->count;
148}
149
150static inline void chash_key(chashiter * iter, chashdatum * result)
151{
152 * result = iter->key;
153}
154
155static inline void chash_value(chashiter * iter, chashdatum * result)
156{
157 * result = iter->value;
158}
159
160#endif
161
162#ifdef __cplusplus
163}
164#endif
165
166#endif
diff --git a/kmicromail/libetpan/include/libetpan/cinthash.h b/kmicromail/libetpan/include/libetpan/cinthash.h
new file mode 100644
index 0000000..7e59dff
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/cinthash.h
@@ -0,0 +1,69 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef CINTHASH_H
37
38#define CINTHASH_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44typedef struct cinthash_t {
45 struct cinthash_list * table;
46 unsigned long hashtable_size ;
47 unsigned long count;
48} cinthash_t;
49
50cinthash_t * cinthash_new(unsigned long hashtable_size);
51void cinthash_free(cinthash_t * table);
52
53int cinthash_add(cinthash_t * table, unsigned long hash, void * data);
54int cinthash_remove(cinthash_t * table, unsigned long hash);
55void * cinthash_find(cinthash_t * table, unsigned long hash);
56
57void cinthash_foreach_key(cinthash_t * table,
58 void (* func)(unsigned long, void *),
59 void * data);
60
61void cinthash_foreach_data(cinthash_t * table,
62 void (* fun)(void *, void *),
63 void * data);
64
65#ifdef __cplusplus
66}
67#endif
68
69#endif
diff --git a/kmicromail/libetpan/include/libetpan/clist.h b/kmicromail/libetpan/include/libetpan/clist.h
new file mode 100644
index 0000000..bd97f59
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/clist.h
@@ -0,0 +1,134 @@
1
2/*
3 * libEtPan! -- a mail stuff library
4 *
5 * clist - Implements simple generic double-linked pointer lists
6 *
7 * Copyright (c) 1999-2000, Gaël Roualland <gael.roualland@iname.com>
8 * interface changes - 2002 - DINH Viet Hoa
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the libEtPan! project nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36/*
37 * $Id$
38 */
39
40#ifndef CLIST_H
41#define CLIST_H
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47typedef struct clistcell_s {
48 void * data;
49 struct clistcell_s * previous;
50 struct clistcell_s * next;
51} clistcell;
52
53struct clist_s {
54 clistcell * first;
55 clistcell * last;
56 int count;
57};
58
59typedef struct clist_s clist;
60typedef clistcell clistiter;
61
62/* Allocate a new pointer list */
63clist * clist_new();
64
65/* Destroys a list. Data pointed by data pointers is NOT freed. */
66void clist_free(clist *);
67
68/* Some of the following routines can be implemented as macros to
69 be faster. If you don't want it, define NO_MACROS */
70#ifdef NO_MACROS
71
72/* Returns TRUE if list is empty */
73int clist_isempty(clist *);
74
75/* Returns the number of elements in the list */
76int clist_count(clist *);
77
78/* Returns an iterator to the first element of the list */
79clistiter * clist_begin(clist *);
80
81/* Returns an iterator to the last element of the list */
82clistiter * clist_end(clist *);
83
84/* Returns an iterator to the next element of the list */
85clistiter * clist_next(clistiter *);
86
87/* Returns an iterator to the previous element of the list */
88clistiter * clist_previous(clistiter *);
89
90/* Returns the data pointer of this element of the list */
91void* clist_content(clistiter *);
92
93/* Inserts this data pointer at the beginning of the list */
94int clist_prepend(clist *, void *);
95
96/* Inserts this data pointer at the end of the list */
97int clist_append(clist *, void *);
98#else
99#define clist_isempty(lst) ((lst->first==lst->last) && (lst->last==NULL))
100#define clist_count(lst) (lst->count)
101#define clist_begin(lst) (lst->first)
102#define clist_end(lst) (lst->last)
103#define clist_next(iter) (iter ? iter->next : NULL)
104#define clist_previous(iter) (iter ? iter->previous : NULL)
105#define clist_content(iter) (iter ? iter->data : NULL)
106#define clist_prepend(lst, data) (clist_insert_before(lst, lst->first, data))
107#define clist_append(lst, data) (clist_insert_after(lst, lst->last, data))
108#endif
109
110/* Inserts this data pointer before the element pointed by the iterator */
111int clist_insert_before(clist *, clistiter *, void *);
112
113/* Inserts this data pointer after the element pointed by the iterator */
114int clist_insert_after(clist *, clistiter *, void *);
115
116/* Deletes the element pointed by the iterator.
117 Returns an iterator to the next element. */
118clistiter * clist_delete(clist *, clistiter *);
119
120typedef void (* clist_func)(void *, void *);
121
122void clist_foreach(clist * lst, clist_func func, void * data);
123
124void clist_concat(clist * dest, clist * src);
125
126void * clist_nth_data(clist * lst, int index);
127
128clistiter * clist_nth(clist * lst, int index);
129
130#ifdef __cplusplus
131}
132#endif
133
134#endif
diff --git a/kmicromail/libetpan/include/libetpan/data_message_driver.h b/kmicromail/libetpan/include/libetpan/data_message_driver.h
new file mode 100644
index 0000000..e0ee752
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/data_message_driver.h
@@ -0,0 +1,50 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef DATA_MESSAGE_DRIVER_H
37
38#define DATA_MESSAGE_DRIVER_H
39
40#include <libetpan/mailmessage.h>
41
42#define LIBETPAN_DATA_MESSAGE
43
44extern mailmessage_driver * data_message_driver;
45
46mailmessage * data_message_init(char * data, size_t len);
47
48void data_message_detach_mime(mailmessage * msg);
49
50#endif
diff --git a/kmicromail/libetpan/include/libetpan/generic_cache_types.h b/kmicromail/libetpan/include/libetpan/generic_cache_types.h
new file mode 100644
index 0000000..8803a42
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/generic_cache_types.h
@@ -0,0 +1,56 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef GENERIC_CACHE_TYPE_H
37
38#define GENERIC_CACHE_TYPE_H
39
40#include <libetpan/carray.h>
41#include <libetpan/chash.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47struct mail_flags_store {
48 carray * fls_tab;
49 chash * fls_hash;
50};
51
52#ifdef __cplusplus
53}
54#endif
55
56#endif
diff --git a/kmicromail/libetpan/include/libetpan/imapdriver.h b/kmicromail/libetpan/include/libetpan/imapdriver.h
new file mode 100644
index 0000000..2bf36c7
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/imapdriver.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef IMAPDRIVER_H
37
38#define IMAPDRIVER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/imapdriver_types.h>
45
46extern mailsession_driver * imap_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/imapdriver_cached.h b/kmicromail/libetpan/include/libetpan/imapdriver_cached.h
new file mode 100644
index 0000000..92bb60d
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/imapdriver_cached.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef IMAPDRIVER_CACHED_H
37
38#define IMAPDRIVER_CACHED_H
39
40#include <libetpan/imapdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * imap_cached_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/imapdriver_cached_message.h b/kmicromail/libetpan/include/libetpan/imapdriver_cached_message.h
new file mode 100644
index 0000000..49d63cb
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/imapdriver_cached_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef IMAPDRIVER_CACHED_MESSAGE_H
37
38#define IMAPDRIVER_CACHED_MESSAGE_H
39
40#include <libetpan/imapdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * imap_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/imapdriver_message.h b/kmicromail/libetpan/include/libetpan/imapdriver_message.h
new file mode 100644
index 0000000..9142633
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/imapdriver_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef IMAPDRIVER_MESSAGE_H
37
38#define IMAPDRIVER_MESSAGE_H
39
40#include <libetpan/imapdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * imap_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/imapdriver_types.h b/kmicromail/libetpan/include/libetpan/imapdriver_types.h
new file mode 100644
index 0000000..d4e216d
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/imapdriver_types.h
@@ -0,0 +1,144 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef IMAPDRIVER_TYPES_H
37
38#define IMAPDRIVER_TYPES_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/mailimap.h>
43#include <libetpan/maildriver_types.h>
44#include <libetpan/generic_cache_types.h>
45#include <libetpan/mailstorage_types.h>
46
47#ifdef __cplusplus
48extern "C" {
49#endif
50
51/* IMAP driver for session */
52
53struct imap_session_state_data {
54 mailimap * imap_session;
55 char * imap_mailbox;
56 struct mail_flags_store * imap_flags_store;
57};
58
59enum {
60 IMAP_SECTION_MESSAGE,
61 IMAP_SECTION_HEADER,
62 IMAP_SECTION_MIME,
63 IMAP_SECTION_BODY
64};
65
66/* cached IMAP driver for session */
67
68enum {
69 IMAPDRIVER_CACHED_SET_CACHE_DIRECTORY = 1,
70};
71
72struct imap_cached_session_state_data {
73 mailsession * imap_ancestor;
74 char * imap_quoted_mb;
75 char imap_cache_directory[PATH_MAX];
76 carray * imap_uid_list;
77};
78
79
80/* IMAP storage */
81
82/*
83 imap_mailstorage is the state data specific to the IMAP4rev1 storage.
84
85 - servername this is the name of the IMAP4rev1 server
86
87 - port is the port to connect to, on the server.
88 you give 0 to use the default port.
89
90 - command, if non-NULL the command used to connect to the
91 server instead of allowing normal TCP connections to be used.
92
93 - connection_type is the type of socket layer to use.
94 The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
95 CONNECTION_TYPE_TRY_STARTTLS, CONNECTION_TYPE_TLS or
96 CONNECTION_TYPE_COMMAND.
97
98 - auth_type is the authenticate mechanism to use.
99 The value can be IMAP_AUTH_TYPE_PLAIN.
100 Other values are not yet implemented.
101
102 - login is the login of the IMAP4rev1 account.
103
104 - password is the password of the IMAP4rev1 account.
105
106 - cached if this value is != 0, a persistant cache will be
107 stored on local system.
108
109 - cache_directory is the location of the cache
110*/
111
112struct imap_mailstorage {
113 char * imap_servername;
114 uint16_t imap_port;
115 char * imap_command;
116 int imap_connection_type;
117
118 int imap_auth_type;
119 char * imap_login;
120 char * imap_password;
121
122 int imap_cached;
123 char * imap_cache_directory;
124};
125
126/* this is the type of IMAP4rev1 authentication */
127
128enum {
129 IMAP_AUTH_TYPE_PLAIN, /* plain text authentication */
130 IMAP_AUTH_TYPE_SASL_ANONYMOUS, /* SASL anonymous */
131 IMAP_AUTH_TYPE_SASL_CRAM_MD5, /* SASL CRAM MD5 */
132 IMAP_AUTH_TYPE_SASL_KERBEROS_V4, /* SASL KERBEROS V4 */
133 IMAP_AUTH_TYPE_SASL_PLAIN, /* SASL plain */
134 IMAP_AUTH_TYPE_SASL_SCRAM_MD5, /* SASL SCRAM MD5 */
135 IMAP_AUTH_TYPE_SASL_GSSAPI, /* SASL GSSAPI */
136 IMAP_AUTH_TYPE_SASL_DIGEST_MD5, /* SASL digest MD5 */
137};
138
139
140#ifdef __cplusplus
141}
142#endif
143
144#endif
diff --git a/kmicromail/libetpan/include/libetpan/imapstorage.h b/kmicromail/libetpan/include/libetpan/imapstorage.h
new file mode 100644
index 0000000..ebc42b0
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/imapstorage.h
@@ -0,0 +1,90 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef IMAPSTORAGE_H
37
38#define IMAPSTORAGE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/imapdriver_types.h>
45
46/*
47 imap_mailstorage_init is the constructor for a IMAP4rev1 storage
48
49 @param storage this is the storage to initialize.
50
51 @param servername this is the name of the IMAP4rev1 server
52
53 @param port is the port to connect to, on the server.
54 you give 0 to use the default port.
55
56 @param command the command used to connect to the server instead of
57 allowing normal TCP connections to be used.
58
59 @param connection_type is the type of socket layer to use.
60 The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
61 CONNECTION_TYPE_TRY_STARTTLS, CONNECTION_TYPE_TLS,
62 CONNECTION_TYPE_COMMAND, CONNECTION_TYPE_COMMAND_STARTTLS,
63 CONNECTION_TYPE_COMMAND_TRY_STARTTLS, CONNECTION_TYPE_COMMAND_TLS,.
64
65 @param auth_type is the authenticate mechanism to use.
66 The value can be IMAP_AUTH_TYPE_PLAIN.
67 Other values are not yet implemented.
68
69 @param login is the login of the IMAP4rev1 account.
70
71 @param password is the password of the IMAP4rev1 account.
72
73 @param cached if this value is != 0, a persistant cache will be
74 stored on local system.
75
76 @param cache_directory is the location of the cache
77*/
78
79int imap_mailstorage_init(struct mailstorage * storage,
80 char * imap_servername, uint16_t imap_port,
81 char * imap_command,
82 int imap_connection_type, int imap_auth_type,
83 char * imap_login, char * imap_password,
84 int imap_cached, char * imap_cache_directory);
85
86#ifdef __cplusplus
87}
88#endif
89
90#endif
diff --git a/kmicromail/libetpan/include/libetpan/libetpan-config.h b/kmicromail/libetpan/include/libetpan/libetpan-config.h
new file mode 100644
index 0000000..20d1e62
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/libetpan-config.h
@@ -0,0 +1,7 @@
1#ifndef LIBETPAN_CONFIG_H
2#define LIBETPAN_CONFIG_H
3#include <limits.h>
4#include <sys/param.h>
5#define MAIL_DIR_SEPARATOR '/'
6#define MAIL_DIR_SEPARATOR_S "/"
7#endif
diff --git a/kmicromail/libetpan/include/libetpan/libetpan.h b/kmicromail/libetpan/include/libetpan/libetpan.h
new file mode 100644
index 0000000..3b4a107
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/libetpan.h
@@ -0,0 +1,104 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef LIBETPAN_H
37
38#define LIBETPAN_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/libetpan_version.h>
45#include <libetpan/maildriver.h>
46#include <libetpan/mailmessage.h>
47#include <libetpan/mailstorage.h>
48#include <libetpan/mailthread.h>
49#include <libetpan/mailsmtp.h>
50#include <libetpan/charconv.h>
51
52/* mbox driver */
53#include <libetpan/mboxdriver.h>
54#include <libetpan/mboxdriver_message.h>
55#include <libetpan/mboxdriver_cached.h>
56#include <libetpan/mboxdriver_cached_message.h>
57#include <libetpan/mboxstorage.h>
58
59/* MH driver */
60#include <libetpan/mhdriver.h>
61#include <libetpan/mhdriver_message.h>
62#include <libetpan/mhdriver_cached.h>
63#include <libetpan/mhdriver_cached_message.h>
64#include <libetpan/mhstorage.h>
65
66/* IMAP4rev1 driver */
67#include <libetpan/imapdriver.h>
68#include <libetpan/imapdriver_message.h>
69#include <libetpan/imapdriver_cached.h>
70#include <libetpan/imapdriver_cached_message.h>
71#include <libetpan/imapstorage.h>
72
73/* POP3 driver */
74#include <libetpan/pop3driver.h>
75#include <libetpan/pop3driver_message.h>
76#include <libetpan/pop3driver_cached.h>
77#include <libetpan/pop3driver_cached_message.h>
78#include <libetpan/pop3storage.h>
79
80/* NNTP driver */
81#include <libetpan/nntpdriver.h>
82#include <libetpan/nntpdriver_message.h>
83#include <libetpan/nntpdriver_cached.h>
84#include <libetpan/nntpdriver_cached_message.h>
85#include <libetpan/nntpstorage.h>
86
87/* maildir driver */
88#include <libetpan/maildirdriver.h>
89#include <libetpan/maildirdriver_message.h>
90#include <libetpan/maildirdriver_cached.h>
91#include <libetpan/maildirdriver_cached_message.h>
92#include <libetpan/maildirstorage.h>
93
94/* message which content is given by a MIME structure */
95#include <libetpan/mime_message_driver.h>
96
97/* message which content given by a string */
98#include <libetpan/data_message_driver.h>
99
100#ifdef __cplusplus
101}
102#endif
103
104#endif
diff --git a/kmicromail/libetpan/include/libetpan/libetpan_version.h b/kmicromail/libetpan/include/libetpan/libetpan_version.h
new file mode 100644
index 0000000..5f9e5cf
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/libetpan_version.h
@@ -0,0 +1,51 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef LIBETPAN_VERSION_H
37
38#define LIBETPAN_VERSION_H
39
40#ifndef LIBETPAN_VERSION_MAJOR
41#define LIBETPAN_VERSION_MAJOR 0
42#endif
43
44#ifndef LIBETPAN_VERSION_MINOR
45#define LIBETPAN_VERSION_MINOR 32
46#endif
47
48int libetpan_get_version_major(void);
49int libetpan_get_version_minor(void);
50
51#endif
diff --git a/kmicromail/libetpan/include/libetpan/mail.h b/kmicromail/libetpan/include/libetpan/mail.h
new file mode 100644
index 0000000..d4c63c4
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mail.h
@@ -0,0 +1,56 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAIL_H
37
38#define MAIL_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#ifndef TRUE
45#define TRUE 1
46#endif
47
48#ifndef FALSE
49#define FALSE 0
50#endif
51
52#ifdef __cplusplus
53}
54#endif
55
56#endif
diff --git a/kmicromail/libetpan/include/libetpan/maildir.h b/kmicromail/libetpan/include/libetpan/maildir.h
new file mode 100644
index 0000000..b782484
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/maildir.h
@@ -0,0 +1,60 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIR_H
37
38#define MAILDIR_H
39
40#include <libetpan/maildir_types.h>
41
42struct maildir * maildir_new(const char * path);
43
44void maildir_free(struct maildir * md);
45
46int maildir_update(struct maildir * md);
47
48int maildir_message_add(struct maildir * md,
49 const char * message, size_t size);
50
51int maildir_message_add_file(struct maildir * md, int fd);
52
53char * maildir_message_get(struct maildir * md, const char * uid);
54
55int maildir_message_remove(struct maildir * md, const char * uid);
56
57int maildir_message_change_flags(struct maildir * md,
58 const char * uid, int new_flags);
59
60#endif
diff --git a/kmicromail/libetpan/include/libetpan/maildir_types.h b/kmicromail/libetpan/include/libetpan/maildir_types.h
new file mode 100644
index 0000000..c7e368e
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/maildir_types.h
@@ -0,0 +1,90 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIR_TYPES_H
37
38#define MAILDIR_TYPES_H
39
40#include <sys/types.h>
41#include <unistd.h>
42#include <libetpan/chash.h>
43#include <libetpan/carray.h>
44#include <inttypes.h>
45
46#include <libetpan/libetpan-config.h>
47
48#define LIBETPAN_MAILDIR
49
50enum {
51 MAILDIR_NO_ERROR = 0,
52 MAILDIR_ERROR_CREATE,
53 MAILDIR_ERROR_DIRECTORY,
54 MAILDIR_ERROR_MEMORY,
55 MAILDIR_ERROR_FILE,
56 MAILDIR_ERROR_NOT_FOUND,
57};
58
59#define MAILDIR_FLAG_NEW (1 << 0)
60#define MAILDIR_FLAG_SEEN (1 << 1)
61#define MAILDIR_FLAG_REPLIED (1 << 2)
62#define MAILDIR_FLAG_FLAGGED (1 << 3)
63#define MAILDIR_FLAG_TRASHED (1 << 4)
64
65struct maildir_msg {
66 char * msg_uid;
67 char * msg_filename;
68 int msg_flags;
69};
70
71/*
72 work around for missing #define HOST_NAME_MAX in Linux
73*/
74
75#ifndef HOST_NAME_MAX
76#define HOST_NAME_MAX 255
77#endif
78
79struct maildir {
80 pid_t mdir_pid;
81 char mdir_hostname[HOST_NAME_MAX];
82 char mdir_path[PATH_MAX];
83 uint32_t mdir_counter;
84 time_t mdir_mtime_new;
85 time_t mdir_mtime_cur;
86 carray * mdir_msg_list;
87 chash * mdir_msg_hash;
88};
89
90#endif
diff --git a/kmicromail/libetpan/include/libetpan/maildirdriver.h b/kmicromail/libetpan/include/libetpan/maildirdriver.h
new file mode 100644
index 0000000..f59cf3e
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/maildirdriver.h
@@ -0,0 +1,53 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIRDRIVER_H
37
38#define MAILDIRDRIVER_H
39
40#include <libetpan/maildriver.h>
41#include <libetpan/maildirdriver_types.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47extern mailsession_driver * maildir_session_driver;
48
49#ifdef __cplusplus
50}
51#endif
52
53#endif
diff --git a/kmicromail/libetpan/include/libetpan/maildirdriver_cached.h b/kmicromail/libetpan/include/libetpan/maildirdriver_cached.h
new file mode 100644
index 0000000..81de3c3
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/maildirdriver_cached.h
@@ -0,0 +1,53 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIRDRIVER_CACHED_H
37
38#define MAILDIRDRIVER_CACHED_H
39
40#include <libetpan/maildriver.h>
41#include <libetpan/maildirdriver_types.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47extern mailsession_driver * maildir_cached_session_driver;
48
49#ifdef __cplusplus
50}
51#endif
52
53#endif
diff --git a/kmicromail/libetpan/include/libetpan/maildirdriver_cached_message.h b/kmicromail/libetpan/include/libetpan/maildirdriver_cached_message.h
new file mode 100644
index 0000000..399ecaa
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/maildirdriver_cached_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIRDRIVER_CACHED_MESSAGE_H
37
38#define MAILDIRDRIVER_CACHED_MESSAGE_H
39
40#include <libetpan/maildirdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * maildir_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/maildirdriver_message.h b/kmicromail/libetpan/include/libetpan/maildirdriver_message.h
new file mode 100644
index 0000000..cb378bc
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/maildirdriver_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIRDRIVER_MESSAGE_H
37
38#define MAILDIRDRIVER_MESSAGE_H
39
40#include <libetpan/maildirdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * maildir_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/maildirdriver_types.h b/kmicromail/libetpan/include/libetpan/maildirdriver_types.h
new file mode 100644
index 0000000..cb3661f
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/maildirdriver_types.h
@@ -0,0 +1,96 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIRDRIVER_TYPES_H
37
38#define MAILDIRDRIVER_TYPES_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/maildriver_types.h>
43#include <libetpan/maildir.h>
44#include <libetpan/generic_cache_types.h>
45#include <libetpan/mailstorage_types.h>
46
47#ifdef __cplusplus
48extern "C" {
49#endif
50
51struct maildir_session_state_data {
52 struct maildir * md_session;
53 struct mail_flags_store * md_flags_store;
54};
55
56enum {
57 MAILDIRDRIVER_CACHED_SET_CACHE_DIRECTORY = 1,
58 MAILDIRDRIVER_CACHED_SET_FLAGS_DIRECTORY,
59};
60
61struct maildir_cached_session_state_data {
62 mailsession * md_ancestor;
63 char * md_quoted_mb;
64 struct mail_flags_store * md_flags_store;
65 char md_cache_directory[PATH_MAX];
66 char md_flags_directory[PATH_MAX];
67};
68
69/* maildir storage */
70
71/*
72 maildir_mailstorage is the state data specific to the maildir storage.
73
74 - pathname is the path of the maildir storage.
75
76 - cached if this value is != 0, a persistant cache will be
77 stored on local system.
78
79 - cache_directory is the location of the cache.
80
81 - flags_directory is the location of the flags.
82*/
83
84struct maildir_mailstorage {
85 char * md_pathname;
86
87 int md_cached;
88 char * md_cache_directory;
89 char * md_flags_directory;
90};
91
92#ifdef __cplusplus
93}
94#endif
95
96#endif
diff --git a/kmicromail/libetpan/include/libetpan/maildirstorage.h b/kmicromail/libetpan/include/libetpan/maildirstorage.h
new file mode 100644
index 0000000..d17ea2c
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/maildirstorage.h
@@ -0,0 +1,69 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIRSTORAGE_H
37
38#define MAILDIRSTORAGE_H
39
40#include <libetpan/maildirdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 maildir_mailstorage_init is the constructor for a mbox storage.
48
49 @param storage this is the storage to initialize.
50
51 @param pathname is the directory that contains the mailbox.
52
53 @param cached if this value is != 0, a persistant cache will be
54 stored on local system.
55
56 @param cache_directory is the location of the cache
57
58 @param flags_directory is the location of the flags
59*/
60
61int maildir_mailstorage_init(struct mailstorage * storage,
62 char * md_pathname, int md_cached,
63 char * md_cache_directory, char * md_flags_directory);
64
65#ifdef __cplusplus
66}
67#endif
68
69#endif
diff --git a/kmicromail/libetpan/include/libetpan/maildriver.h b/kmicromail/libetpan/include/libetpan/maildriver.h
new file mode 100644
index 0000000..7da9aea
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/maildriver.h
@@ -0,0 +1,543 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDRIVER_H
37
38#define MAILDRIVER_H
39
40#include <libetpan/maildriver_types.h>
41#include <libetpan/maildriver_types_helper.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47/* mailsession */
48
49/*
50 mailsession_new creates a new session, using the given driver
51
52 @return the created session is returned
53*/
54
55mailsession * mailsession_new(mailsession_driver * sess_driver);
56
57/*
58 mailsession_free release the memory used by the session
59*/
60
61void mailsession_free(mailsession * session);
62
63/*
64 mailsession_parameters is used to make calls specific to the driver
65
66 @param id is the command to send to the driver,
67 usually, commands can be found in the header of the driver
68
69 @param value is the parameter of the specific call
70
71 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
72 on error
73*/
74
75int mailsession_parameters(mailsession * session,
76 int id, void * value);
77
78/*
79 There are drivers of two kinds : stream drivers (driver that connects
80 to servers through TCP or other means of connection) and file drivers
81 (driver that are based on filesystem)
82
83 The following function can only be used by stream drivers.
84 mailsession_connect_stream connects a stream to the session
85
86 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
87 on error
88*/
89
90int mailsession_connect_stream(mailsession * session, mailstream * s);
91
92/*
93 The following function can only be used by file drivers.
94 mailsession_connect_path selects the main path of the session
95
96 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
97 on error
98*/
99
100int mailsession_connect_path(mailsession * session, char * path);
101
102/*
103 NOTE: works only on stream drivers
104
105 mailsession_starttls switches the current connection to TLS (secure layer)
106
107 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
108 on error
109*/
110
111int mailsession_starttls(mailsession * session);
112
113/*
114 mailsession_login notifies the login and the password to authenticate
115 to the session
116
117 @param userid the given string is only needed at this function call
118 (it will be duplicated if necessary)
119 @param password the given string is only needed at this function call
120 (it will be duplicated if necessary)
121
122 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
123 on error
124*/
125
126int mailsession_login(mailsession * session,
127 char * userid, char * password);
128
129/*
130 NOTE: this function doesn't often work on filsystem drivers
131
132 mailsession_logout deconnects the session and closes the stream.
133
134 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
135 on error
136*/
137
138int mailsession_logout(mailsession * session);
139
140/*
141 mailsession_noop does no operation on the session, but it can be
142 used to poll for the status of the connection.
143
144 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
145 on error
146*/
147
148int mailsession_noop(mailsession * session);
149
150/*
151 NOTE: driver's specific should be used
152
153 mailsession_build_folder_name will return an allocated string with
154 that contains the complete path of the folder to create
155
156 @param session the sesion
157 @param mb is the parent mailbox
158 @param name is the name of the folder to create
159 @param result the complete path of the folder to create will be
160 stored in (* result), this name have to be freed with free()
161
162 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
163 on error
164*/
165
166int mailsession_build_folder_name(mailsession * session, char * mb,
167 char * name, char ** result);
168
169/*
170 NOTE: driver's specific should be used
171
172 mailsession_create_folder creates the folder that corresponds to the
173 given name
174
175 @param session the session
176 @param mb is the name of the mailbox
177
178 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
179 on error
180*/
181
182int mailsession_create_folder(mailsession * session, char * mb);
183
184
185/*
186 NOTE: driver's specific should be used
187
188 mailsession_delete_folder deletes the folder that corresponds to the
189 given name
190
191 @param session the session
192 @param mb is the name of the mailbox
193
194 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
195 on error
196*/
197
198int mailsession_delete_folder(mailsession * session, char * mb);
199
200
201/*
202 mailsession_rename_folder changes the name of the folder
203
204 @param session the session
205 @param mb is the name of the mailbox whose name has to be changed
206 @param new_name is the destination name (the parent
207 of the new folder folder can be other)
208
209 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
210 on error
211*/
212
213int mailsession_rename_folder(mailsession * session,
214 char * mb, char * new_name);
215
216/*
217 mailsession_check_folder makes a checkpoint of the session
218
219 @param session the session
220
221 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
222 on error
223*/
224
225int mailsession_check_folder(mailsession * session);
226
227
228/*
229 NOTE: this function is not implemented in most drivers
230
231 mailsession_examine_folder selects a mailbox as readonly
232
233 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
234 on error
235*/
236
237int mailsession_examine_folder(mailsession * session, char * mb);
238
239
240/*
241 mailsession_select_folder selects a mailbox
242
243 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
244 on error
245*/
246
247int mailsession_select_folder(mailsession * session, char * mb);
248
249
250/*
251 mailsession_expunge_folder deletes all messages marked \Deleted
252
253 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
254 on error
255*/
256
257int mailsession_expunge_folder(mailsession * session);
258
259
260/*
261 mailsession_status_folder queries the status of the folder
262 (number of messages, number of recent messages, number of unseen messages)
263
264 @param session the session
265 @param mb mailbox to query
266 @param result_messages the number of messages is stored
267 in (* result_messages)
268 @param result_recent the number of messages is stored
269 in (* result_recent)
270 @param result_unseen the number of messages is stored
271 in (* result_unseen)
272
273 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
274 on error
275*/
276
277int mailsession_status_folder(mailsession * session, char * mb,
278 uint32_t * result_messages, uint32_t * result_recent,
279 uint32_t * result_unseen);
280
281
282/*
283 mailsession_messages_number queries the number of messages in the folder
284
285 @param session the session
286 @param mb mailbox to query
287 @param result the number of messages is stored in (* result)
288
289 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
290 on error
291*/
292
293int mailsession_messages_number(mailsession * session, char * mb,
294 uint32_t * result);
295
296/*
297 mailsession_recent_number queries the number of recent messages in the folder
298
299 @param session the session
300 @param mb mailbox to query
301 @param result the number of recent messages is stored in (* result)
302
303 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
304 on error
305*/
306
307int mailsession_recent_number(mailsession * session,
308 char * mb, uint32_t * result);
309
310/*
311 mailsession_unseen_number queries the number of unseen messages in the folder
312
313 @param session the session
314 @param mb mailbox to query
315 @param result the number of unseen messages is stored in (* result)
316
317 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
318 on error
319*/
320
321int mailsession_unseen_number(mailsession * session, char * mb,
322 uint32_t * result);
323
324/*
325 NOTE: driver's specific should be used
326
327 mailsession_list_folders returns the list of all sub-mailboxes
328 of the given mailbox
329
330 @param session the session
331 @param mb the mailbox
332 @param result list of mailboxes if stored in (* result),
333 this structure have to be freed with mail_list_free()
334
335 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
336 on error
337*/
338
339int mailsession_list_folders(mailsession * session, char * mb,
340 struct mail_list ** result);
341
342/*
343 NOTE: driver's specific should be used
344
345 mailsession_lsub_folders returns the list of subscribed
346 sub-mailboxes of the given mailbox
347
348 @param session the session
349 @param mb the mailbox
350 @param result list of mailboxes if stored in (* result),
351 this structure have to be freed with mail_list_free()
352
353 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
354 on error
355*/
356
357int mailsession_lsub_folders(mailsession * session, char * mb,
358 struct mail_list ** result);
359
360/*
361 NOTE: driver's specific should be used
362
363 mailsession_subscribe_folder subscribes to the given mailbox
364
365 @param session the session
366 @param mb the mailbox
367
368 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
369 on error
370*/
371
372int mailsession_subscribe_folder(mailsession * session, char * mb);
373
374/*
375 NOTE: driver's specific should be used
376
377 mailsession_unsubscribe_folder unsubscribes to the given mailbox
378
379 @param session the session
380 @param mb the mailbox
381
382 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
383 on error
384*/
385
386int mailsession_unsubscribe_folder(mailsession * session, char * mb);
387
388/*
389 mailsession_append_message adds a RFC 2822 message to the current
390 given mailbox
391
392 @param session the session
393 @param message is a string that contains the RFC 2822 message
394 @param size this is the size of the message
395
396 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
397 on error
398*/
399
400int mailsession_append_message(mailsession * session,
401 char * message, size_t size);
402
403/*
404 NOTE: some drivers does not implement this
405
406 mailsession_copy_message copies a message whose number is given to
407 a given mailbox. The mailbox must be accessible from the same session.
408
409 @param session the session
410 @param num the message number
411 @param mb the destination mailbox
412
413 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
414 on error
415*/
416
417int mailsession_copy_message(mailsession * session,
418 uint32_t num, char * mb);
419
420/*
421 NOTE: some drivers does not implement this
422
423 mailsession_move_message copies a message whose number is given to
424 a given mailbox. The mailbox must be accessible from the same session.
425
426 @param session the session
427 @param num the message number
428 @param mb the destination mailbox
429
430 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
431 on error
432*/
433
434int mailsession_move_message(mailsession * session,
435 uint32_t num, char * mb);
436
437/*
438 mailsession_get_messages_list returns the list of message numbers
439 of the current mailbox.
440
441 @param session the session
442 @param result the list of message numbers will be stored in (* result),
443 this structure have to be freed with mailmessage_list_free()
444
445 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
446 on error
447*/
448
449int mailsession_get_messages_list(mailsession * session,
450 struct mailmessage_list ** result);
451
452/*
453 mailsession_get_envelopes_list fills the parsed fields in the
454 mailmessage structures of the mailmessage_list.
455
456 @param session the session
457 @param result this is the list of mailmessage structures
458
459 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
460 on error
461*/
462
463int mailsession_get_envelopes_list(mailsession * session,
464 struct mailmessage_list * result);
465
466/*
467 NOTE: some drivers does not implement this
468
469 mailsession_remove_message removes the given message from the mailbox.
470 The message is permanently deleted.
471
472 @param session the session
473 @param num is the message number
474
475 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
476 on error
477*/
478
479int mailsession_remove_message(mailsession * session, uint32_t num);
480
481
482/*
483 NOTE: this function is not implemented in most drivers
484
485 mailsession_search_message returns a list of message numbers that
486 corresponds to the given criteria.
487
488 @param session the session
489 @param charset is the charset to use (it can be NULL)
490 @param key is the list of criteria
491 @param result the search result is stored in (* result),
492 this structure have to be freed with mail_search_result_free()
493
494 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
495 on error
496*/
497
498#if 0
499int mailsession_search_messages(mailsession * session, char * charset,
500 struct mail_search_key * key,
501 struct mail_search_result ** result);
502#endif
503
504/*
505 mailsession_get_message returns a mailmessage structure that corresponds
506 to the given message number.
507 * WARNING * mailsession_get_message_by_uid() should be used instead.
508
509 @param session the session
510 @param num the message number
511 @param result the allocated mailmessage structure will be stored
512 in (* result), this structure have to be freed with mailmessage_free()
513
514 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
515 on error
516*/
517
518int mailsession_get_message(mailsession * session,
519 uint32_t num, mailmessage ** result);
520
521/*
522 mailsession_get_message_by_uid returns a mailmessage structure
523 that corresponds to the given message unique identifier.
524 This is currently implemented only for cached drivers.
525 * WARNING * That will deprecates the use of mailsession_get_message()
526
527 @param session the session
528 @param uid the message unique identifier
529 @param result the allocated mailmessage structure will be stored
530 in (* result), this structure have to be freed with mailmessage_free()
531
532 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
533 on error
534*/
535
536int mailsession_get_message_by_uid(mailsession * session,
537 const char * uid, mailmessage ** result);
538
539#ifdef __cplusplus
540}
541#endif
542
543#endif
diff --git a/kmicromail/libetpan/include/libetpan/maildriver_errors.h b/kmicromail/libetpan/include/libetpan/maildriver_errors.h
new file mode 100644
index 0000000..118b259
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/maildriver_errors.h
@@ -0,0 +1,99 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDRIVER_ERRORS_H
37
38#define MAILDRIVER_ERRORS_H
39
40enum {
41 MAIL_NO_ERROR = 0,
42 MAIL_NO_ERROR_AUTHENTICATED,
43 MAIL_NO_ERROR_NON_AUTHENTICATED,
44 MAIL_ERROR_NOT_IMPLEMENTED,
45 MAIL_ERROR_UNKNOWN,
46 MAIL_ERROR_CONNECT,
47 MAIL_ERROR_BAD_STATE,
48 MAIL_ERROR_FILE,
49 MAIL_ERROR_STREAM,
50 MAIL_ERROR_LOGIN,
51 MAIL_ERROR_CREATE, /* 10 */
52 MAIL_ERROR_DELETE,
53 MAIL_ERROR_LOGOUT,
54 MAIL_ERROR_NOOP,
55 MAIL_ERROR_RENAME,
56 MAIL_ERROR_CHECK,
57 MAIL_ERROR_EXAMINE,
58 MAIL_ERROR_SELECT,
59 MAIL_ERROR_MEMORY,
60 MAIL_ERROR_STATUS,
61 MAIL_ERROR_SUBSCRIBE, /* 20 */
62 MAIL_ERROR_UNSUBSCRIBE,
63 MAIL_ERROR_LIST,
64 MAIL_ERROR_LSUB,
65 MAIL_ERROR_APPEND,
66 MAIL_ERROR_COPY,
67 MAIL_ERROR_FETCH,
68 MAIL_ERROR_STORE,
69 MAIL_ERROR_SEARCH,
70 MAIL_ERROR_DISKSPACE,
71 MAIL_ERROR_MSG_NOT_FOUND, /* 30 */
72 MAIL_ERROR_PARSE,
73 MAIL_ERROR_INVAL,
74 MAIL_ERROR_PART_NOT_FOUND,
75 MAIL_ERROR_REMOVE,
76 MAIL_ERROR_FOLDER_NOT_FOUND,
77 MAIL_ERROR_MOVE,
78 MAIL_ERROR_STARTTLS,
79 MAIL_ERROR_CACHE_MISS,
80 MAIL_ERROR_NO_TLS,
81 MAIL_ERROR_EXPUNGE,
82 /* misc errors */
83 MAIL_ERROR_MISC,
84 MAIL_ERROR_PROTOCOL,
85 MAIL_ERROR_CAPABILITY,
86 MAIL_ERROR_CLOSE,
87 MAIL_ERROR_FATAL,
88 MAIL_ERROR_READONLY,
89 MAIL_ERROR_NO_APOP,
90 MAIL_ERROR_COMMAND_NOT_SUPPORTED,
91 MAIL_ERROR_NO_PERMISSION,
92 MAIL_ERROR_PROGRAM_ERROR,
93 MAIL_ERROR_SUBJECT_NOT_FOUND,
94 MAIL_ERROR_CHAR_ENCODING_FAILED,
95 MAIL_ERROR_SEND,
96 MAIL_ERROR_COMMAND,
97};
98
99#endif
diff --git a/kmicromail/libetpan/include/libetpan/maildriver_types.h b/kmicromail/libetpan/include/libetpan/maildriver_types.h
new file mode 100644
index 0000000..3ff9440
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/maildriver_types.h
@@ -0,0 +1,793 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDRIVER_TYPES_H
37
38#define MAILDRIVER_TYPES_H
39
40#include <inttypes.h>
41#include <sys/types.h>
42
43#include <libetpan/mailstream.h>
44#include <libetpan/mailimf.h>
45#include <libetpan/mailmime.h>
46#include <libetpan/carray.h>
47
48#include <libetpan/mailthread_types.h>
49#include <libetpan/maildriver_errors.h>
50
51#ifdef __cplusplus
52extern "C" {
53#endif
54
55typedef struct mailsession_driver mailsession_driver;
56
57typedef struct mailsession mailsession;
58
59typedef struct mailmessage_driver mailmessage_driver;
60
61typedef struct mailmessage mailmessage;
62
63
64/*
65 mailmessage_list is a list of mailmessage
66
67 - tab is an array of mailmessage structures
68*/
69
70struct mailmessage_list {
71 carray * msg_tab; /* elements are (mailmessage *) */
72};
73
74struct mailmessage_list * mailmessage_list_new(carray * msg_tab);
75void mailmessage_list_free(struct mailmessage_list * env_list);
76
77/*
78 mail_list is a list of mailbox names
79
80 - list is a list of mailbox names
81*/
82
83struct mail_list {
84 clist * mb_list; /* elements are (char *) */
85};
86
87struct mail_list * mail_list_new(clist * mb_list);
88void mail_list_free(struct mail_list * resp);
89
90/*
91 This is a flag value.
92 Flags can be combined with OR operation
93*/
94
95enum {
96 MAIL_FLAG_NEW = 1 << 0,
97 MAIL_FLAG_SEEN = 1 << 1,
98 MAIL_FLAG_FLAGGED = 1 << 2,
99 MAIL_FLAG_DELETED = 1 << 3,
100 MAIL_FLAG_ANSWERED = 1 << 4,
101 MAIL_FLAG_FORWARDED = 1 << 5,
102 MAIL_FLAG_CANCELLED = 1 << 6,
103};
104
105/*
106 mail_flags is the value of a flag related to a message.
107
108 - flags is the standard flags value
109
110 - extension is a list of unknown flags for libEtPan!
111*/
112
113struct mail_flags {
114 uint32_t fl_flags;
115 clist * fl_extension; /* elements are (char *) */
116};
117
118struct mail_flags * mail_flags_new(uint32_t fl_flags, clist * fl_ext);
119void mail_flags_free(struct mail_flags * flags);
120
121/*
122 This function creates a flag for a new message
123*/
124
125struct mail_flags * mail_flags_new_empty(void);
126
127
128/*
129 mailimf_date_time_comp compares two dates
130
131
132*/
133
134int32_t mailimf_date_time_comp(struct mailimf_date_time * date1,
135 struct mailimf_date_time * date2);
136
137/*
138 this is type type of the search criteria
139*/
140
141enum {
142 MAIL_SEARCH_KEY_ALL, /* all messages correspond */
143 MAIL_SEARCH_KEY_ANSWERED, /* messages with flag \Answered */
144 MAIL_SEARCH_KEY_BCC, /* messages which Bcc field contains
145 a given string */
146 MAIL_SEARCH_KEY_BEFORE, /* messages which internal date is earlier
147 than the specified date */
148 MAIL_SEARCH_KEY_BODY, /* message that contains the given string
149 (in header and text parts) */
150 MAIL_SEARCH_KEY_CC, /* messages whose Cc field contains the
151 given string */
152 MAIL_SEARCH_KEY_DELETED, /* messages with the flag \Deleted */
153 MAIL_SEARCH_KEY_FLAGGED, /* messages with the flag \Flagged */
154 MAIL_SEARCH_KEY_FROM, /* messages whose From field contains the
155 given string */
156 MAIL_SEARCH_KEY_NEW, /* messages with the flag \Recent and not
157 the \Seen flag */
158 MAIL_SEARCH_KEY_OLD, /* messages that do not have the
159 \Recent flag set */
160 MAIL_SEARCH_KEY_ON, /* messages whose internal date is the
161 specified date */
162 MAIL_SEARCH_KEY_RECENT, /* messages with the flag \Recent */
163 MAIL_SEARCH_KEY_SEEN, /* messages with the flag \Seen */
164 MAIL_SEARCH_KEY_SINCE, /* messages whose internal date is later
165 than specified date */
166 MAIL_SEARCH_KEY_SUBJECT, /* messages whose Subject field contains the
167 given string */
168 MAIL_SEARCH_KEY_TEXT, /* messages whose text part contains the
169 given string */
170 MAIL_SEARCH_KEY_TO, /* messages whose To field contains the
171 given string */
172 MAIL_SEARCH_KEY_UNANSWERED, /* messages with no flag \Answered */
173 MAIL_SEARCH_KEY_UNDELETED, /* messages with no flag \Deleted */
174 MAIL_SEARCH_KEY_UNFLAGGED, /* messages with no flag \Flagged */
175 MAIL_SEARCH_KEY_UNSEEN, /* messages with no flag \Seen */
176 MAIL_SEARCH_KEY_HEADER, /* messages whose given field
177 contains the given string */
178 MAIL_SEARCH_KEY_LARGER, /* messages whose size is larger then
179 the given size */
180 MAIL_SEARCH_KEY_NOT, /* not operation of the condition */
181 MAIL_SEARCH_KEY_OR, /* or operation between two conditions */
182 MAIL_SEARCH_KEY_SMALLER, /* messages whose size is smaller than
183 the given size */
184 MAIL_SEARCH_KEY_MULTIPLE /* the boolean operator between the
185 conditions is AND */
186};
187
188/*
189 mail_search_key is the condition on the messages to return
190
191 - type is the type of the condition
192
193 - bcc is the text to search in the Bcc field when type is
194 MAIL_SEARCH_KEY_BCC, should be allocated with malloc()
195
196 - before is a date when type is MAIL_SEARCH_KEY_BEFORE
197
198 - body is the text to search in the message when type is
199 MAIL_SEARCH_KEY_BODY, should be allocated with malloc()
200
201 - cc is the text to search in the Cc field when type is
202 MAIL_SEARCH_KEY_CC, should be allocated with malloc()
203
204 - from is the text to search in the From field when type is
205 MAIL_SEARCH_KEY_FROM, should be allocated with malloc()
206
207 - on is a date when type is MAIL_SEARCH_KEY_ON
208
209 - since is a date when type is MAIL_SEARCH_KEY_SINCE
210
211 - subject is the text to search in the Subject field when type is
212 MAILIMAP_SEARCH_KEY_SUBJECT, should be allocated with malloc()
213
214 - text is the text to search in the text part of the message when
215 type is MAILIMAP_SEARCH_KEY_TEXT, should be allocated with malloc()
216
217 - to is the text to search in the To field when type is
218 MAILIMAP_SEARCH_KEY_TO, should be allocated with malloc()
219
220 - header_name is the header name when type is MAILIMAP_SEARCH_KEY_HEADER,
221 should be allocated with malloc()
222
223 - header_value is the text to search in the given header when type is
224 MAILIMAP_SEARCH_KEY_HEADER, should be allocated with malloc()
225
226 - larger is a size when type is MAILIMAP_SEARCH_KEY_LARGER
227
228 - not is a condition when type is MAILIMAP_SEARCH_KEY_NOT
229
230 - or1 is a condition when type is MAILIMAP_SEARCH_KEY_OR
231
232 - or2 is a condition when type is MAILIMAP_SEARCH_KEY_OR
233
234 - sentbefore is a date when type is MAILIMAP_SEARCH_KEY_SENTBEFORE
235
236 - senton is a date when type is MAILIMAP_SEARCH_KEY_SENTON
237
238 - sentsince is a date when type is MAILIMAP_SEARCH_KEY_SENTSINCE
239
240 - smaller is a size when type is MAILIMAP_SEARCH_KEY_SMALLER
241
242 - multiple is a set of message when type is MAILIMAP_SEARCH_KEY_MULTIPLE
243*/
244
245#if 0
246struct mail_search_key {
247 int sk_type;
248 union {
249 char * sk_bcc;
250 struct mailimf_date_time * sk_before;
251 char * sk_body;
252 char * sk_cc;
253 char * sk_from;
254 struct mailimf_date_time * sk_on;
255 struct mailimf_date_time * sk_since;
256 char * sk_subject;
257 char * sk_text;
258 char * sk_to;
259 char * sk_header_name;
260 char * sk_header_value;
261 size_t sk_larger;
262 struct mail_search_key * sk_not;
263 struct mail_search_key * sk_or1;
264 struct mail_search_key * sk_or2;
265 size_t sk_smaller;
266 clist * sk_multiple; /* list of (struct mailimap_search_key *) */
267 } sk_data;
268};
269
270
271struct mail_search_key *
272mail_search_key_new(int sk_type,
273 char * sk_bcc, struct mailimf_date_time * sk_before,
274 char * sk_body, char * sk_cc, char * sk_from,
275 struct mailimf_date_time * sk_on, struct mailimf_date_time * sk_since,
276 char * sk_subject, char * sk_text, char * sk_to,
277 char * sk_header_name, char * sk_header_value, size_t sk_larger,
278 struct mail_search_key * sk_not, struct mail_search_key * sk_or1,
279 struct mail_search_key * sk_or2, size_t sk_smaller,
280 clist * sk_multiple);
281
282void mail_search_key_free(struct mail_search_key * key);
283#endif
284
285/*
286 mail_search_result is a list of message numbers that is returned
287 by the mailsession_search_messages function()
288*/
289
290#if 0
291struct mail_search_result {
292 clist * sr_list; /* list of (uint32_t *) */
293};
294
295struct mail_search_result * mail_search_result_new(clist * sr_list);
296
297void mail_search_result_free(struct mail_search_result * search_result);
298#endif
299
300
301/*
302 There is three kinds of identities :
303 - storage
304 - folders
305 - session
306
307 A storage (struct mailstorage) represents whether a server or
308 a main path,
309
310 A storage can be an IMAP server, the root path of a MH or a mbox file.
311
312 Folders (struct mailfolder) are the mailboxes we can
313 choose in the server or as sub-folder of the main path.
314
315 Folders for IMAP are the IMAP mailboxes, for MH this is one of the
316 folder of the MH storage, for mbox, there is only one folder, the
317 mbox file content;
318
319 A mail session (struct mailsession) is whether a connection to a server
320 or a path that is open. It is the abstraction lower folders and storage.
321 It allow us to send commands.
322
323 We have a session driver for mail session for each kind of storage.
324
325 From a session, we can get a message (struct mailmessage) to read.
326 We have a message driver for each kind of storage.
327*/
328
329/*
330 maildriver is the driver structure for mail sessions
331
332 - name is the name of the driver
333
334 - initialize() is the function that will initializes a data structure
335 specific to the driver, it returns a value that will be stored
336 in the field data of the session.
337 The field data of the session is the state of the session,
338 the internal data structure used by the driver.
339 It is called when creating the mailsession structure with
340 mailsession_new().
341
342 - uninitialize() frees the structure created with initialize()
343
344 - parameters() implements functions specific to the given mail access
345
346 - connect_stream() connects a stream to the session
347
348 - connect_path() notify a main path to the session
349
350 - starttls() changes the current stream to a TLS stream
351
352 - login() notifies the user and the password to authenticate to the
353 session
354
355 - logout() exits the session and closes the stream
356
357 - noop() does no operation on the session, but it can be
358 used to poll for the status of the connection.
359
360 - build_folder_name() will return an allocated string with
361 that contains the complete path of the folder to create
362
363 - create_folder() creates the folder that corresponds to the
364 given name
365
366 - delete_folder() deletes the folder that corresponds to the
367 given name
368
369 - rename_folder() change the name of the folder
370
371 - check_folder() makes a checkpoint of the session
372
373 - examine_folder() selects a mailbox as readonly
374
375 - select_folder() selects a mailbox
376
377 - expunge_folder() deletes all messages marked \Deleted
378
379 - status_folder() queries the status of the folder
380 (number of messages, number of recent messages, number of
381 unseen messages)
382
383 - messages_number() queries the number of messages in the folder
384
385 - recent_number() queries the number of recent messages in the folder
386
387 - unseen_number() queries the number of unseen messages in the folder
388
389 - list_folders() returns the list of all sub-mailboxes
390 of the given mailbox
391
392 - lsub_folders() returns the list of subscribed
393 sub-mailboxes of the given mailbox
394
395 - subscribe_folder() subscribes to the given mailbox
396
397 - unsubscribe_folder() unsubscribes to the given mailbox
398
399 - append_message() adds a RFC 2822 message to the current
400 given mailbox
401
402 - copy_message() copies a message whose number is given to
403 a given mailbox. The mailbox must be accessible from
404 the same session.
405
406 - move_message() copies a message whose number is given to
407 a given mailbox. The mailbox must be accessible from the
408 same session.
409
410 - get_messages_list() returns the list of message numbers
411 of the current mailbox.
412
413 - get_envelopes_list() fills the parsed fields in the
414 mailmessage structures of the mailmessage_list.
415
416 - remove_message() removes the given message from the mailbox.
417 The message is permanently deleted.
418
419 - search_message() returns a list of message numbers that
420 corresponds to the given criteria.
421
422 - get_message returns a mailmessage structure that corresponds
423 to the given message number.
424
425 - get_message_by_uid returns a mailmessage structure that corresponds
426 to the given message unique identifier.
427
428 * mandatory functions are the following :
429
430 - connect_stream() of connect_path()
431 - logout()
432 - get_messages_list()
433 - get_envelopes_list()
434
435 * we advise you to implement these functions :
436
437 - select_folder() (in case a session can access several folders)
438 - noop() (to check if the server is responding)
439 - check_folder() (to make a checkpoint of the session)
440 - status_folder(), messages_number(), recent_number(), unseen_number()
441 (to get stat of the folder)
442 - append_message() (but can't be done in the case of POP3 at least)
443 - login() in a case of an authenticated driver.
444 - starttls() in a case of a stream driver, if the procotol supports
445 STARTTLS.
446 - get_message_by_uid() so that the application can remember the message
447 by UID and build its own list of messages.
448
449 * drivers' specific :
450
451 Everything that is specific to the driver will be implemented in this
452 function :
453
454 - parameters()
455*/
456
457struct mailsession_driver {
458 char * sess_name;
459
460 int (* sess_initialize)(mailsession * session);
461 void (* sess_uninitialize)(mailsession * session);
462
463 int (* sess_parameters)(mailsession * session,
464 int id, void * value);
465
466 int (* sess_connect_stream)(mailsession * session, mailstream * s);
467 int (* sess_connect_path)(mailsession * session, char * path);
468
469 int (* sess_starttls)(mailsession * session);
470
471 int (* sess_login)(mailsession * session, char * userid, char * password);
472 int (* sess_logout)(mailsession * session);
473 int (* sess_noop)(mailsession * session);
474
475 /* folders operations */
476
477 int (* sess_build_folder_name)(mailsession * session, char * mb,
478 char * name, char ** result);
479
480 int (* sess_create_folder)(mailsession * session, char * mb);
481 int (* sess_delete_folder)(mailsession * session, char * mb);
482 int (* sess_rename_folder)(mailsession * session, char * mb,
483 char * new_name);
484 int (* sess_check_folder)(mailsession * session);
485 int (* sess_examine_folder)(mailsession * session, char * mb);
486 int (* sess_select_folder)(mailsession * session, char * mb);
487 int (* sess_expunge_folder)(mailsession * session);
488 int (* sess_status_folder)(mailsession * session, char * mb,
489 uint32_t * result_num, uint32_t * result_recent,
490 uint32_t * result_unseen);
491 int (* sess_messages_number)(mailsession * session, char * mb,
492 uint32_t * result);
493 int (* sess_recent_number)(mailsession * session, char * mb,
494 uint32_t * result);
495 int (* sess_unseen_number)(mailsession * session, char * mb,
496 uint32_t * result);
497
498 int (* sess_list_folders)(mailsession * session, char * mb,
499 struct mail_list ** result);
500 int (* sess_lsub_folders)(mailsession * session, char * mb,
501 struct mail_list ** result);
502
503 int (* sess_subscribe_folder)(mailsession * session, char * mb);
504 int (* sess_unsubscribe_folder)(mailsession * session, char * mb);
505
506 /* messages operations */
507
508 int (* sess_append_message)(mailsession * session,
509 char * message, size_t size);
510 int (* sess_copy_message)(mailsession * session,
511 uint32_t num, char * mb);
512 int (* sess_move_message)(mailsession * session,
513 uint32_t num, char * mb);
514
515 int (* sess_get_message)(mailsession * session,
516 uint32_t num, mailmessage ** result);
517
518 int (* sess_get_message_by_uid)(mailsession * session,
519 const char * uid, mailmessage ** result);
520
521 int (* sess_get_messages_list)(mailsession * session,
522 struct mailmessage_list ** result);
523 int (* sess_get_envelopes_list)(mailsession * session,
524 struct mailmessage_list * env_list);
525 int (* sess_remove_message)(mailsession * session, uint32_t num);
526#if 0
527 int (* sess_search_messages)(mailsession * session, char * charset,
528 struct mail_search_key * key,
529 struct mail_search_result ** result);
530#endif
531};
532
533
534/*
535 session is the data structure for a mail session.
536
537 - data is the internal data structure used by the driver
538 It is called when initializing the mailsession structure.
539
540 - driver is the driver used for the session
541*/
542
543struct mailsession {
544 void * sess_data;
545 mailsession_driver * sess_driver;
546};
547
548
549
550
551/*
552 mailmessage_driver is the driver structure to get information from messages.
553
554 - name is the name of the driver
555
556 - initialize() is the function that will initializes a data structure
557 specific to the driver, it returns a value that will be stored
558 in the field data of the mailsession.
559 The field data of the session is the state of the session,
560 the internal data structure used by the driver.
561 It is called when initializing the mailmessage structure with
562 mailmessage_init().
563
564 - uninitialize() frees the structure created with initialize().
565 It will be called by mailmessage_free().
566
567 - flush() will free from memory all temporary structures of the message
568 (for example, the MIME structure of the message).
569
570 - fetch_result_free() will free all strings resulted by fetch() or
571 any fetch_xxx() functions that returns a string.
572
573 - fetch() returns the content of the message (headers and text).
574
575 - fetch_header() returns the content of the headers.
576
577 - fetch_body() returns the message text (message content without headers)
578
579 - fetch_size() returns the size of the message content.
580
581 - get_bodystructure() returns the MIME structure of the message.
582
583 - fetch_section() returns the content of a given MIME part
584
585 - fetch_section_header() returns the header of the message
586 contained by the given MIME part.
587
588 - fetch_section_mime() returns the MIME headers of the
589 given MIME part.
590
591 - fetch_section_body() returns the text (if this is a message, this is the
592 message content without headers) of the given MIME part.
593
594 - fetch_envelope() returns a mailimf_fields structure, with a list of
595 fields chosen by the driver.
596
597 - get_flags() returns a the flags related to the message.
598 When you want to get flags of a message, you have to make sure to
599 call get_flags() at least once before using directly message->flags.
600*/
601
602#define LIBETPAN_MAIL_MESSAGE_CHECK
603
604struct mailmessage_driver {
605 char * msg_name;
606
607 int (* msg_initialize)(mailmessage * msg_info);
608
609 void (* msg_uninitialize)(mailmessage * msg_info);
610
611 void (* msg_flush)(mailmessage * msg_info);
612
613 void (* msg_check)(mailmessage * msg_info);
614
615 void (* msg_fetch_result_free)(mailmessage * msg_info,
616 char * msg);
617
618 int (* msg_fetch)(mailmessage * msg_info,
619 char ** result,
620 size_t * result_len);
621
622 int (* msg_fetch_header)(mailmessage * msg_info,
623 char ** result,
624 size_t * result_len);
625
626 int (* msg_fetch_body)(mailmessage * msg_info,
627 char ** result, size_t * result_len);
628
629 int (* msg_fetch_size)(mailmessage * msg_info,
630 size_t * result);
631
632 int (* msg_get_bodystructure)(mailmessage * msg_info,
633 struct mailmime ** result);
634
635 int (* msg_fetch_section)(mailmessage * msg_info,
636 struct mailmime * mime,
637 char ** result, size_t * result_len);
638
639 int (* msg_fetch_section_header)(mailmessage * msg_info,
640 struct mailmime * mime,
641 char ** result,
642 size_t * result_len);
643
644 int (* msg_fetch_section_mime)(mailmessage * msg_info,
645 struct mailmime * mime,
646 char ** result,
647 size_t * result_len);
648
649 int (* msg_fetch_section_body)(mailmessage * msg_info,
650 struct mailmime * mime,
651 char ** result,
652 size_t * result_len);
653
654 int (* msg_fetch_envelope)(mailmessage * msg_info,
655 struct mailimf_fields ** result);
656
657 int (* msg_get_flags)(mailmessage * msg_info,
658 struct mail_flags ** result);
659};
660
661
662/*
663 mailmessage is a data structure to get information from messages
664
665 - session is the session linked to the given message, it can be NULL
666
667 - driver is the message driver
668
669 - index is the message number
670
671 - uid, when it is not NULL, it means that the folder
672 the folder has persistant message numbers, the string is
673 the unique message number in the folder.
674 uid should be implemented if possible.
675 for drivers where we cannot generate real uid,
676 a suggestion is "AAAA-IIII" where AAAA is some
677 random session number and IIII the content of index field.
678
679 - size, when it is not 0, is the size of the message content.
680
681 - fields, when it is not NULL, are the header fields of the message.
682
683 - flags, when it is not NULL, are the flags related to the message.
684
685 - single_fields, when resolved != 0, is filled with the data of fields.
686
687 - mime, when it is not NULL
688
689 - cached is != 0 when the header fields were read from the cache.
690
691 - data is data specific to the driver, this is internal data structure,
692 some state of the message.
693*/
694
695struct mailmessage {
696 mailsession * msg_session;
697 mailmessage_driver * msg_driver;
698 uint32_t msg_index;
699 char * msg_uid;
700
701 size_t msg_size;
702 struct mailimf_fields * msg_fields;
703 struct mail_flags * msg_flags;
704
705 int msg_resolved;
706 struct mailimf_single_fields msg_single_fields;
707 struct mailmime * msg_mime;
708
709 /* internal data */
710
711 int msg_cached;
712 void * msg_data;
713
714 /*
715 msg_folder field :
716 used to reference the mailfolder, this is a workaround due
717 to the problem with initial conception, where folder notion
718 did not exist.
719 */
720 void * msg_folder;
721 /* user data */
722 void * msg_user_data;
723};
724
725
726/*
727 mailmessage_tree is a node in the messages tree (thread)
728
729 - parent is the parent of the message, it is NULL if the message
730 is the root of the message tree.
731
732 - date is the date of the message in number of second elapsed
733 since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).
734
735 - msg is the message structure that is stored referenced by the node.
736 is msg is NULL, this is a dummy node.
737
738 - children is an array that contains all the children of the node.
739 children are mailmessage_tree structures.
740
741 - is_reply is != 0 when the message is a reply or a forward
742
743 - base_subject is the extracted subject of the message.
744
745 - index is the message number.
746*/
747
748struct mailmessage_tree {
749 struct mailmessage_tree * node_parent;
750 char * node_msgid;
751 time_t node_date;
752 mailmessage * node_msg;
753 carray * node_children; /* array of (struct mailmessage_tree *) */
754
755 /* private, used for threading */
756 int node_is_reply;
757 char * node_base_subject;
758};
759
760
761struct mailmessage_tree *
762mailmessage_tree_new(char * node_msgid, time_t node_date,
763 mailmessage * node_msg);
764
765void mailmessage_tree_free(struct mailmessage_tree * tree);
766
767/*
768 mailmessage_tree_free_recursive
769
770 if you want to release memory of the given tree and all the sub-trees,
771 you can use this function.
772*/
773
774void mailmessage_tree_free_recursive(struct mailmessage_tree * tree);
775
776
777struct generic_message_t {
778 int (* msg_prefetch)(mailmessage * msg_info);
779 void (* msg_prefetch_free)(struct generic_message_t * msg);
780 int msg_fetched;
781 char * msg_message;
782 size_t msg_length;
783 void * msg_data;
784};
785
786
787const char * maildriver_strerror(int err);
788
789#ifdef __cplusplus
790}
791#endif
792
793#endif
diff --git a/kmicromail/libetpan/include/libetpan/maildriver_types_helper.h b/kmicromail/libetpan/include/libetpan/maildriver_types_helper.h
new file mode 100644
index 0000000..2e74dea
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/maildriver_types_helper.h
@@ -0,0 +1,99 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDRIVER_TYPES_HELPER_H
37
38#define MAILDRIVER_TYPES_HELPER_H
39
40#include <libetpan/maildriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 mail_flags_add_extension adds the given flag if it does not exists in
48 the flags.
49
50 @param flags this is the flag to change
51
52 @param ext_flag this is the name of an extension flag
53 the given flag name is duplicated and is no more needed after
54 the function call.
55
56 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
57 on error
58*/
59
60int mail_flags_add_extension(struct mail_flags * flags,
61 char * ext_flag);
62
63/*
64 mail_flags_remove_extension removes the given flag if it does not exists in
65 the flags.
66
67 @param flags this is the flag to change
68
69 @param ext_flag this is the name of an extension flag
70 the given flag name is no more needed after the function call.
71
72 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
73 on error
74*/
75
76int mail_flags_remove_extension(struct mail_flags * flags,
77 char * ext_flag);
78
79/*
80 mail_flags_has_extension returns 1 if the flags is in the given flags,
81 0 is returned otherwise.
82
83 @param flags this is the flag to change
84
85 @param ext_flag this is the name of an extension flag
86 the given flag name is no more needed after the function call.
87
88 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
89 on error
90*/
91
92int mail_flags_has_extension(struct mail_flags * flags,
93 char * ext_flag);
94
95#ifdef __cplusplus
96}
97#endif
98
99#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailfolder.h b/kmicromail/libetpan/include/libetpan/mailfolder.h
new file mode 100644
index 0000000..3ecad23
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailfolder.h
@@ -0,0 +1,32 @@
1#ifndef MAILFOLDER_H
2
3#define MAILFOLDER_H
4
5#include "mailstorage_types.h"
6
7int mailfolder_noop(struct mailfolder * folder);
8
9int mailfolder_check(struct mailfolder * folder);
10
11int mailfolder_expunge(struct mailfolder * folder);
12
13int mailfolder_status(struct mailfolder * folder,
14 uint32_t * result_messages, uint32_t * result_recent,
15 uint32_t * result_unseen);
16
17int mailfolder_append_message(struct mailfolder * folder,
18 char * message, size_t size);
19
20int mailfolder_get_messages_list(struct mailfolder * folder,
21 struct mailmessage_list ** result);
22
23int mailfolder_get_envelopes_list(struct mailfolder * folder,
24 struct mailmessage_list * result);
25
26int mailfolder_get_message(struct mailfolder * folder,
27 uint32_t num, mailmessage ** result);
28
29int mailfolder_get_message_by_uid(struct mailfolder * folder,
30 const char * uid, mailmessage ** result);
31
32#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailimap.h b/kmicromail/libetpan/include/libetpan/mailimap.h
new file mode 100644
index 0000000..8dfa3d4
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailimap.h
@@ -0,0 +1,598 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_H
37
38#define MAILIMAP_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailimap_types.h>
45#include <libetpan/mailimap_types_helper.h>
46#include <libetpan/mailimap_helper.h>
47
48#include <libetpan/mailimap_socket.h>
49#include <libetpan/mailimap_ssl.h>
50
51/*
52 mailimap_connect()
53
54 This function will connect the IMAP session with the given stream.
55
56 @param session the IMAP session
57 @param s stream to use
58
59 @return the return code is one of MAILIMAP_ERROR_XXX or
60 MAILIMAP_NO_ERROR codes
61
62 note that on success, MAILIMAP_NO_ERROR_AUTHENTICATED or
63 MAILIMAP_NO_ERROR_NON_AUTHENTICATED is returned
64
65 MAILIMAP_NO_ERROR_NON_AUTHENTICATED is returned when you need to
66 use mailimap_login() to authenticate, else
67 MAILIMAP_NO_ERROR_AUTHENTICATED is returned.
68*/
69
70int mailimap_connect(mailimap * session, mailstream * s);
71
72/*
73 mailimap_append()
74
75 This function will append a given message to the given mailbox
76 by sending an APPEND command.
77
78 @param session the IMAP session
79 @param mailbox name of the mailbox
80 @param flag_list flags of the message
81 @param date_time timestamp of the message
82 @param literal content of the message
83 @param literal_size size of the message
84
85 @return the return code is one of MAILIMAP_ERROR_XXX or
86 MAILIMAP_NO_ERROR codes
87*/
88
89int mailimap_append(mailimap * session, const char * mailbox,
90 struct mailimap_flag_list * flag_list,
91 struct mailimap_date_time * date_time,
92 const char * literal, size_t literal_size);
93
94/*
95 mailimap_noop()
96
97 This function will poll for an event on the server by
98 sending a NOOP command to the IMAP server
99
100 @param session IMAP session
101
102 @return the return code is one of MAILIMAP_ERROR_XXX or
103 MAILIMAP_NO_ERROR_XXX codes
104*/
105
106int mailimap_noop(mailimap * session);
107
108/*
109 mailimap_logout()
110
111 This function will logout from an IMAP server by sending
112 a LOGOUT command.
113
114 @param session IMAP session
115
116 @return the return code is one of MAILIMAP_ERROR_XXX or
117 MAILIMAP_NO_ERROR codes
118*/
119
120int mailimap_logout(mailimap * session);
121
122/*
123 mailimap_capability()
124
125 This function will query an IMAP server for his capabilities
126 by sending a CAPABILITY command.
127
128 @param session IMAP session
129 @param result The result of this command is a list of
130 capabilities and it is stored into (* result).
131
132 @return the return code is one of MAILIMAP_ERROR_XXX or
133 MAILIMAP_NO_ERROR codes
134 */
135
136int mailimap_capability(mailimap * session,
137 struct mailimap_capability_data ** result);
138
139/*
140 mailimap_check()
141
142 This function will request for a checkpoint of the mailbox by
143 sending a CHECK command.
144
145 @param session IMAP session
146
147 @return the return code is one of MAILIMAP_ERROR_XXX or
148 MAILIMAP_NO_ERROR codes
149 */
150
151int mailimap_check(mailimap * session);
152
153/*
154 mailimap_close()
155
156 This function will close the selected mailbox by sending
157 a CLOSE command.
158
159 @param session IMAP session
160
161 @return the return code is one of MAILIMAP_ERROR_XXX or
162 MAILIMAP_NO_ERROR codes
163 */
164
165int mailimap_close(mailimap * session);
166
167/*
168 mailimap_expunge()
169
170 This function will permanently remove from the selected mailbox
171 message that have the \Deleted flag set.
172
173 @param session IMAP session
174
175 @return the return code is one of MAILIMAP_ERROR_XXX or
176 MAILIMAP_NO_ERROR codes
177*/
178
179int mailimap_expunge(mailimap * session);
180
181/*
182 mailimap_copy()
183
184 This function will copy the given messages from the selected mailbox
185 to the given mailbox.
186
187 @param session IMAP session
188 @param set This is a set of message numbers.
189 @param mb This is the destination mailbox.
190
191 @return the return code is one of MAILIMAP_ERROR_XXX or
192 MAILIMAP_NO_ERROR codes
193 */
194
195int mailimap_copy(mailimap * session, struct mailimap_set * set,
196 const char * mb);
197
198/*
199 mailimap_uid_copy()
200
201 This function will copy the given messages from the selected mailbox
202 to the given mailbox.
203
204 @param session IMAP session
205 @param set This is a set of message unique identifiers.
206 @param mb This is the destination mailbox.
207
208 @return the return code is one of MAILIMAP_ERROR_XXX or
209 MAILIMAP_NO_ERROR codes
210 */
211
212int mailimap_uid_copy(mailimap * session,
213 struct mailimap_set * set, const char * mb);
214
215/*
216 mailimap_create()
217
218 This function will create a mailbox.
219
220 @param session IMAP session
221 @param mb This is the name of the mailbox to create.
222
223 @return the return code is one of MAILIMAP_ERROR_XXX or
224 MAILIMAP_NO_ERROR codes
225*/
226
227int mailimap_create(mailimap * session, const char * mb);
228
229/*
230 mailimap_delete()
231
232 This function will delete a mailox.
233
234 @param session IMAP session
235 @param mb This is the name of the mailbox to delete.
236
237 @return the return code is one of MAILIMAP_ERROR_XXX or
238 MAILIMAP_NO_ERROR codes
239*/
240
241int mailimap_delete(mailimap * session, const char * mb);
242
243/*
244 mailimap_examine()
245
246 This function will select the mailbox for read-only operations.
247
248 @param session IMAP session
249 @param mb This is the name of the mailbox to select.
250
251 @return the return code is one of MAILIMAP_ERROR_XXX or
252 MAILIMAP_NO_ERROR codes
253*/
254
255int mailimap_examine(mailimap * session, const char * mb);
256
257/*
258 mailimap_fetch()
259
260 This function will retrieve data associated with the given message
261 numbers.
262
263 @param session IMAP session
264 @param set set of message numbers
265 @param fetch_type type of information to be retrieved
266 @param result The result of this command is a clist
267 and it is stored into (* result). Each element of the clist is a
268 (struct mailimap_msg_att *).
269
270 @return the return code is one of MAILIMAP_ERROR_XXX or
271 MAILIMAP_NO_ERROR codes
272*/
273
274int
275mailimap_fetch(mailimap * session, struct mailimap_set * set,
276 struct mailimap_fetch_type * fetch_type, clist ** result);
277
278/*
279 mailimap_fetch()
280
281 This function will retrieve data associated with the given message
282 numbers.
283
284 @param session IMAP session
285 @param set set of message unique identifiers
286 @param fetch_type type of information to be retrieved
287 @param result The result of this command is a clist
288 and it is stored into (* result). Each element of the clist is a
289 (struct mailimap_msg_att *).
290
291 @return the return code is one of MAILIMAP_ERROR_XXX or
292 MAILIMAP_NO_ERROR codes
293*/
294
295int
296mailimap_uid_fetch(mailimap * session,
297 struct mailimap_set * set,
298 struct mailimap_fetch_type * fetch_type, clist ** result);
299
300/*
301 mailimap_fetch_list_free()
302
303 This function will free the result of a fetch command.
304
305 @param fetch_list This is the clist containing
306 (struct mailimap_msg_att *) elements to free.
307*/
308
309void mailimap_fetch_list_free(clist * fetch_list);
310
311/*
312 mailimap_list()
313
314 This function will return the list of the mailbox
315 available on the server.
316
317 @param session IMAP session
318 @param mb This is the reference name that informs
319 of the level of hierarchy
320 @param list_mb mailbox name with possible wildcard
321 @param result This will store a clist of (struct mailimap_mailbox_list *)
322 in (* result)
323
324 @return the return code is one of MAILIMAP_ERROR_XXX or
325 MAILIMAP_NO_ERROR codes
326*/
327
328int mailimap_list(mailimap * session, const char * mb,
329 const char * list_mb, clist ** result);
330
331/*
332 mailimap_login()
333
334 This function will authenticate the client.
335
336 @param session IMAP session
337 @param userid login of the user
338 @param password password of the user
339
340 @return the return code is one of MAILIMAP_ERROR_XXX or
341 MAILIMAP_NO_ERROR codes
342*/
343
344int mailimap_login(mailimap * session,
345 const char * userid, const char * password);
346
347/*
348 mailimap_lsub()
349
350 This function will return the list of the mailbox
351 that the client has subscribed to.
352
353 @param session IMAP session
354 @param mb This is the reference name that informs
355 of the level of hierarchy
356 @param list_mb mailbox name with possible wildcard
357 @param result This will store a list of (struct mailimap_mailbox_list *)
358 in (* result)
359
360 @return the return code is one of MAILIMAP_ERROR_XXX or
361 MAILIMAP_NO_ERROR codes
362*/
363
364int mailimap_lsub(mailimap * session, const char * mb,
365 const char * list_mb, clist ** result);
366
367/*
368 mailimap_list_result_free()
369
370 This function will free the clist of (struct mailimap_mailbox_list *)
371
372 @param list This is the clist to free.
373*/
374
375void mailimap_list_result_free(clist * list);
376
377/*
378 mailimap_rename()
379
380 This function will change the name of a mailbox.
381
382 @param session IMAP session
383 @param mb current name
384 @param new_name new name
385
386 @return the return code is one of MAILIMAP_ERROR_XXX or
387 MAILIMAP_NO_ERROR codes
388*/
389
390int mailimap_rename(mailimap * session,
391 const char * mb, const char * new_name);
392
393/*
394 mailimap_search()
395
396 All mails that match the given criteria will be returned
397 their numbers in the result list.
398
399 @param session IMAP session
400 @param charset This indicates the charset of the strings that appears
401 in the searching criteria
402 @param key This is the searching criteria
403 @param result The result is a clist of (uint32_t *) and will be
404 stored in (* result).
405
406 @return the return code is one of MAILIMAP_ERROR_XXX or
407 MAILIMAP_NO_ERROR codes
408*/
409
410int
411mailimap_search(mailimap * session, const char * charset,
412 struct mailimap_search_key * key, clist ** result);
413
414/*
415 mailimap_uid_search()
416
417
418 All mails that match the given criteria will be returned
419 their unique identifiers in the result list.
420
421 @param session IMAP session
422 @param charset This indicates the charset of the strings that appears
423 in the searching criteria
424 @param key This is the searching criteria
425 @param result The result is a clist of (uint32_t *) and will be
426 stored in (* result).
427
428 @return the return code is one of MAILIMAP_ERROR_XXX or
429 MAILIMAP_NO_ERROR codes
430*/
431
432int
433mailimap_uid_search(mailimap * session, const char * charset,
434 struct mailimap_search_key * key, clist ** result);
435
436/*
437 mailimap_search_result_free()
438
439 This function will free the result of the a search.
440
441 @param search_result This is a clist of (uint32_t *) returned
442 by mailimap_uid_search() or mailimap_search()
443*/
444
445void mailimap_search_result_free(clist * search_result);
446
447/*
448 mailimap_select()
449
450 This function will select a given mailbox so that messages in the
451 mailbox can be accessed.
452
453 @param session IMAP session
454 @param mb This is the name of the mailbox to select.
455
456 @return the return code is one of MAILIMAP_ERROR_XXX or
457 MAILIMAP_NO_ERROR codes
458*/
459
460int
461mailimap_select(mailimap * session, const char * mb);
462
463/*
464 mailimap_status()
465
466 This function will return informations about a given mailbox.
467
468 @param session IMAP session
469 @param mb This is the name of the mailbox
470 @param status_att_list This is the list of mailbox information to return
471 @param result List of returned values
472
473 @return the return code is one of MAILIMAP_ERROR_XXX or
474 MAILIMAP_NO_ERROR codes
475*/
476
477int
478mailimap_status(mailimap * session, const char * mb,
479 struct mailimap_status_att_list * status_att_list,
480 struct mailimap_mailbox_data_status ** result);
481
482/*
483 mailimap_uid_store()
484
485 This function will alter the data associated with some messages
486 (flags of the messages).
487
488 @param session IMAP session
489 @param set This is a list of message numbers.
490 @param store_att_flags This is the data to associate with the
491 given messages
492
493 @return the return code is one of MAILIMAP_ERROR_XXX or
494 MAILIMAP_NO_ERROR codes
495*/
496
497int
498mailimap_store(mailimap * session,
499 struct mailimap_set * set,
500 struct mailimap_store_att_flags * store_att_flags);
501
502/*
503 mailimap_uid_store()
504
505 This function will alter the data associated with some messages
506 (flags of the messages).
507
508 @param session IMAP session
509 @param set This is a list of message unique identifiers.
510 @param store_att_flags This is the data to associate with the
511 given messages
512
513 @return the return code is one of MAILIMAP_ERROR_XXX or
514 MAILIMAP_NO_ERROR codes
515*/
516
517int
518mailimap_uid_store(mailimap * session,
519 struct mailimap_set * set,
520 struct mailimap_store_att_flags * store_att_flags);
521
522/*
523 mailimap_subscribe()
524
525 This function adds the specified mailbox name to the
526 server's set of "active" or "subscribed" mailboxes.
527
528 @param session IMAP session
529 @param mb This is the name of the mailbox
530
531 @return the return code is one of MAILIMAP_ERROR_XXX or
532 MAILIMAP_NO_ERROR codes
533*/
534
535int mailimap_subscribe(mailimap * session, const char * mb);
536
537/*
538 mailimap_unsubscribe()
539
540 This function removes the specified mailbox name to the
541 server's set of "active" or "subscribed" mailboxes.
542
543 @param session IMAP session
544 @param mb This is the name of the mailbox
545
546 @return the return code is one of MAILIMAP_ERROR_XXX or
547 MAILIMAP_NO_ERROR codes
548*/
549
550int mailimap_unsubscribe(mailimap * session, const char * mb);
551
552/*
553 mailimap_starttls()
554
555 This function starts change the mode of the connection to
556 switch to SSL connection.
557
558 @param session IMAP session
559
560 @return the return code is one of MAILIMAP_ERROR_XXX or
561 MAILIMAP_NO_ERROR_XXX codes
562 */
563
564int mailimap_starttls(mailimap * session);
565
566/*
567 mailimap_new()
568
569 This function returns a new IMAP session.
570
571 @param progr_rate When downloading messages, a function will be called
572 each time the amount of bytes downloaded reaches a multiple of this
573 value, this can be 0.
574 @param progr_fun This is the function to call to notify the progress,
575 this can be NULL.
576
577 @return an IMAP session is returned.
578 */
579
580mailimap * mailimap_new(size_t imap_progr_rate,
581 progress_function * imap_progr_fun);
582
583/*
584 mailimap_free()
585
586 This function will free the data structures associated with
587 the IMAP session.
588
589 @param session IMAP session
590 */
591
592void mailimap_free(mailimap * session);
593
594#ifdef __cplusplus
595}
596#endif
597
598#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailimap_helper.h b/kmicromail/libetpan/include/libetpan/mailimap_helper.h
new file mode 100644
index 0000000..d73cf5f
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailimap_helper.h
@@ -0,0 +1,66 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_HELPER_H
37
38#define MAILIMAP_HELPER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailimap_types.h>
45
46int mailimap_fetch_rfc822(mailimap * session,
47 uint32_t msgid, char ** result);
48
49int mailimap_fetch_rfc822_header(mailimap * session,
50 uint32_t msgid, char ** result);
51
52int mailimap_fetch_envelope(mailimap * session,
53 uint32_t first, uint32_t last,
54 clist ** result);
55
56int mailimap_append_simple(mailimap * session, char * mailbox,
57 char * content, uint32_t size);
58
59int mailimap_login_simple(mailimap * session,
60 char * userid, char * password);
61
62#ifdef __cplusplus
63}
64#endif
65
66#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailimap_socket.h b/kmicromail/libetpan/include/libetpan/mailimap_socket.h
new file mode 100644
index 0000000..aadc67e
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailimap_socket.h
@@ -0,0 +1,54 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_SOCKET_H
37
38#define MAILIMAP_SOCKET_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45
46#include <libetpan/mailimap_types.h>
47
48int mailimap_socket_connect(mailimap * f, const char * server, uint16_t port);
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailimap_ssl.h b/kmicromail/libetpan/include/libetpan/mailimap_ssl.h
new file mode 100644
index 0000000..76906a0
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailimap_ssl.h
@@ -0,0 +1,54 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_SSL_H
37
38#define MAILIMAP_SSL_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45
46#include <libetpan/mailimap_types.h>
47
48int mailimap_ssl_connect(mailimap * f, const char * server, uint16_t port);
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailimap_types.h b/kmicromail/libetpan/include/libetpan/mailimap_types.h
new file mode 100644
index 0000000..2996b53
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailimap_types.h
@@ -0,0 +1,3274 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36/*
37 IMAP4rev1 grammar
38
39 address = "(" addr-name SP addr-adl SP addr-mailbox SP
40 addr-host ")"
41
42 addr-adl = nstring
43 ; Holds route from [RFC-822] route-addr if
44 ; non-NIL
45
46 addr-host = nstring
47 ; NIL indicates [RFC-822] group syntax.
48 ; Otherwise, holds [RFC-822] domain name
49
50 addr-mailbox = nstring
51 ; NIL indicates end of [RFC-822] group; if
52 ; non-NIL and addr-host is NIL, holds
53 ; [RFC-822] group name.
54 ; Otherwise, holds [RFC-822] local-part
55 ; after removing [RFC-822] quoting
56
57
58
59 addr-name = nstring
60 ; If non-NIL, holds phrase from [RFC-822]
61 ; mailbox after removing [RFC-822] quoting
62
63 append = "APPEND" SP mailbox [SP flag-list] [SP date-time] SP
64 literal
65
66 astring = 1*ASTRING-CHAR / string
67
68 ASTRING-CHAR = ATOM-CHAR / resp-specials
69
70 atom = 1*ATOM-CHAR
71
72 ATOM-CHAR = <any CHAR except atom-specials>
73
74 atom-specials = "(" / ")" / "{" / SP / CTL / list-wildcards /
75 quoted-specials / resp-specials
76
77 authenticate = "AUTHENTICATE" SP auth-type *(CRLF base64)
78
79 auth-type = atom
80 ; Defined by [SASL]
81
82 base64 = *(4base64-char) [base64-terminal]
83
84 base64-char = ALPHA / DIGIT / "+" / "/"
85 ; Case-sensitive
86
87 base64-terminal = (2base64-char "==") / (3base64-char "=")
88
89 body = "(" (body-type-1part / body-type-mpart) ")"
90
91 body-extension = nstring / number /
92 "(" body-extension *(SP body-extension) ")"
93 ; Future expansion. Client implementations
94 ; MUST accept body-extension fields. Server
95 ; implementations MUST NOT generate
96 ; body-extension fields except as defined by
97 ; future standard or standards-track
98 ; revisions of this specification.
99
100 body-ext-1part = body-fld-md5 [SP body-fld-dsp [SP body-fld-lang
101 *(SP body-extension)]]
102 ; MUST NOT be returned on non-extensible
103 ; "BODY" fetch
104
105
106 body-ext-mpart = body-fld-param [SP body-fld-dsp [SP body-fld-lang
107 *(SP body-extension)]]
108 ; MUST NOT be returned on non-extensible
109 ; "BODY" fetch
110
111 body-fields = body-fld-param SP body-fld-id SP body-fld-desc SP
112 body-fld-enc SP body-fld-octets
113
114 body-fld-desc = nstring
115
116 body-fld-dsp = "(" string SP body-fld-param ")" / nil
117
118 body-fld-enc = (DQUOTE ("7BIT" / "8BIT" / "BINARY" / "BASE64"/
119 "QUOTED-PRINTABLE") DQUOTE) / string
120
121 body-fld-id = nstring
122
123 body-fld-lang = nstring / "(" string *(SP string) ")"
124
125 body-fld-lines = number
126
127 body-fld-md5 = nstring
128
129 body-fld-octets = number
130
131 body-fld-param = "(" string SP string *(SP string SP string) ")" / nil
132
133 body-type-1part = (body-type-basic / body-type-msg / body-type-text)
134 [SP body-ext-1part]
135
136 body-type-basic = media-basic SP body-fields
137 ; MESSAGE subtype MUST NOT be "RFC822"
138
139 body-type-mpart = 1*body SP media-subtype
140 [SP body-ext-mpart]
141
142 body-type-msg = media-message SP body-fields SP envelope
143 SP body SP body-fld-lines
144
145 body-type-text = media-text SP body-fields SP body-fld-lines
146
147 capability = ("AUTH=" auth-type) / atom
148 ; New capabilities MUST begin with "X" or be
149 ; registered with IANA as standard or
150 ; standards-track
151
152
153 capability-data = "CAPABILITY" *(SP capability) SP "IMAP4rev1"
154 *(SP capability)
155 ; IMAP4rev1 servers which offer RFC 1730
156 ; compatibility MUST list "IMAP4" as the first
157 ; capability.
158
159 CHAR8 = %x01-ff
160 ; any OCTET except NUL, %x00
161
162 command = tag SP (command-any / command-auth / command-nonauth /
163 command-select) CRLF
164 ; Modal based on state
165
166 command-any = "CAPABILITY" / "LOGOUT" / "NOOP" / x-command
167 ; Valid in all states
168
169 command-auth = append / create / delete / examine / list / lsub /
170 rename / select / status / subscribe / unsubscribe
171 ; Valid only in Authenticated or Selected state
172
173 command-nonauth = login / authenticate
174 ; Valid only when in Not Authenticated state
175
176 command-select = "CHECK" / "CLOSE" / "EXPUNGE" / copy / fetch / store /
177 uid / search
178 ; Valid only when in Selected state
179
180 continue-req = "+" SP (resp-text / base64) CRLF
181
182 copy = "COPY" SP set SP mailbox
183
184 create = "CREATE" SP mailbox
185 ; Use of INBOX gives a NO error
186
187 date = date-text / DQUOTE date-text DQUOTE
188
189 date-day = 1*2DIGIT
190 ; Day of month
191
192 date-day-fixed = (SP DIGIT) / 2DIGIT
193 ; Fixed-format version of date-day
194
195 date-month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" /
196 "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
197
198 date-text = date-day "-" date-month "-" date-year
199
200 date-year = 4DIGIT
201
202 date-time = DQUOTE date-day-fixed "-" date-month "-" date-year
203 SP time SP zone DQUOTE
204
205 delete = "DELETE" SP mailbox
206 ; Use of INBOX gives a NO error
207
208 digit-nz = %x31-39
209 ; 1-9
210
211 envelope = "(" env-date SP env-subject SP env-from SP env-sender SP
212 env-reply-to SP env-to SP env-cc SP env-bcc SP
213 env-in-reply-to SP env-message-id ")"
214
215 env-bcc = "(" 1*address ")" / nil
216
217 env-cc = "(" 1*address ")" / nil
218
219 env-date = nstring
220
221 env-from = "(" 1*address ")" / nil
222
223 env-in-reply-to = nstring
224
225 env-message-id = nstring
226
227 env-reply-to = "(" 1*address ")" / nil
228
229 env-sender = "(" 1*address ")" / nil
230
231 env-subject = nstring
232
233 env-to = "(" 1*address ")" / nil
234
235 examine = "EXAMINE" SP mailbox
236
237 fetch = "FETCH" SP set SP ("ALL" / "FULL" / "FAST" / fetch-att /
238 "(" fetch-att *(SP fetch-att) ")")
239
240 fetch-att = "ENVELOPE" / "FLAGS" / "INTERNALDATE" /
241 "RFC822" [".HEADER" / ".SIZE" / ".TEXT"] /
242 "BODY" ["STRUCTURE"] / "UID" /
243 "BODY" [".PEEK"] section ["<" number "." nz-number ">"]
244
245 flag = "\Answered" / "\Flagged" / "\Deleted" /
246 "\Seen" / "\Draft" / flag-keyword / flag-extension
247 ; Does not include "\Recent"
248
249 flag-extension = "\" atom
250 ; Future expansion. Client implementations
251 ; MUST accept flag-extension flags. Server
252 ; implementations MUST NOT generate
253 ; flag-extension flags except as defined by
254 ; future standard or standards-track
255 ; revisions of this specification.
256
257 flag-fetch = flag / "\Recent"
258
259 flag-keyword = atom
260
261 flag-list = "(" [flag *(SP flag)] ")"
262
263 flag-perm = flag / "\*"
264
265 greeting = "*" SP (resp-cond-auth / resp-cond-bye) CRLF
266
267 header-fld-name = astring
268
269 header-list = "(" header-fld-name *(SP header-fld-name) ")"
270
271 list = "LIST" SP mailbox SP list-mailbox
272
273 list-mailbox = 1*list-char / string
274
275 list-char = ATOM-CHAR / list-wildcards / resp-specials
276
277 list-wildcards = "%" / "*"
278
279 literal = "{" number "}" CRLF *CHAR8
280 ; Number represents the number of CHAR8s
281
282 login = "LOGIN" SP userid SP password
283
284 lsub = "LSUB" SP mailbox SP list-mailbox
285
286 mailbox = "INBOX" / astring
287 ; INBOX is case-insensitive. All case variants of
288 ; INBOX (e.g. "iNbOx") MUST be interpreted as INBOX
289 ; not as an astring. An astring which consists of
290 ; the case-insensitive sequence "I" "N" "B" "O" "X"
291 ; is considered to be INBOX and not an astring.
292 ; Refer to section 5.1 for further
293 ; semantic details of mailbox names.
294
295 mailbox-data = "FLAGS" SP flag-list / "LIST" SP mailbox-list /
296 "LSUB" SP mailbox-list / "SEARCH" *(SP nz-number) /
297 "STATUS" SP mailbox SP "("
298 [status-att SP number *(SP status-att SP number)] ")" /
299 number SP "EXISTS" / number SP "RECENT"
300
301 mailbox-list = "(" [mbx-list-flags] ")" SP
302 (DQUOTE QUOTED-CHAR DQUOTE / nil) SP mailbox
303
304 mbx-list-flags = *(mbx-list-oflag SP) mbx-list-sflag
305 *(SP mbx-list-oflag) /
306 mbx-list-oflag *(SP mbx-list-oflag)
307
308 mbx-list-oflag = "\Noinferiors" / flag-extension
309 ; Other flags; multiple possible per LIST response
310
311 mbx-list-sflag = "\Noselect" / "\Marked" / "\Unmarked"
312 ; Selectability flags; only one per LIST response
313
314 media-basic = ((DQUOTE ("APPLICATION" / "AUDIO" / "IMAGE" / "MESSAGE" /
315 "VIDEO") DQUOTE) / string) SP media-subtype
316 ; Defined in [MIME-IMT]
317
318 media-message = DQUOTE "MESSAGE" DQUOTE SP DQUOTE "RFC822" DQUOTE
319 ; Defined in [MIME-IMT]
320
321 media-subtype = string
322 ; Defined in [MIME-IMT]
323
324 media-text = DQUOTE "TEXT" DQUOTE SP media-subtype
325 ; Defined in [MIME-IMT]
326
327 message-data = nz-number SP ("EXPUNGE" / ("FETCH" SP msg-att))
328
329 msg-att = "(" (msg-att-dynamic / msg-att-static)
330 *(SP (msg-att-dynamic / msg-att-static)) ")"
331
332 msg-att-dynamic = "FLAGS" SP "(" [flag-fetch *(SP flag-fetch)] ")"
333 ; MAY change for a message
334
335 msg-att-static = "ENVELOPE" SP envelope / "INTERNALDATE" SP date-time /
336 "RFC822" [".HEADER" / ".TEXT"] SP nstring /
337 "RFC822.SIZE" SP number / "BODY" ["STRUCTURE"] SP body /
338 "BODY" section ["<" number ">"] SP nstring /
339 "UID" SP uniqueid
340 ; MUST NOT change for a message
341
342 nil = "NIL"
343
344 nstring = string / nil
345
346 number = 1*DIGIT
347 ; Unsigned 32-bit integer
348 ; (0 <= n < 4,294,967,296)
349
350 nz-number = digit-nz *DIGIT
351 ; Non-zero unsigned 32-bit integer
352 ; (0 < n < 4,294,967,296)
353
354 password = astring
355
356 quoted = DQUOTE *QUOTED-CHAR DQUOTE
357
358 QUOTED-CHAR = <any TEXT-CHAR except quoted-specials> /
359 "\" quoted-specials
360
361 quoted-specials = DQUOTE / "\"
362
363 rename = "RENAME" SP mailbox SP mailbox
364 ; Use of INBOX as a destination gives a NO error
365
366 response = *(continue-req / response-data) response-done
367
368 response-data = "*" SP (resp-cond-state / resp-cond-bye /
369 mailbox-data / message-data / capability-data) CRLF
370
371 response-done = response-tagged / response-fatal
372
373 response-fatal = "*" SP resp-cond-bye CRLF
374 ; Server closes connection immediately
375
376 response-tagged = tag SP resp-cond-state CRLF
377
378 resp-cond-auth = ("OK" / "PREAUTH") SP resp-text
379 ; Authentication condition
380
381 resp-cond-bye = "BYE" SP resp-text
382
383 resp-cond-state = ("OK" / "NO" / "BAD") SP resp-text
384 ; Status condition
385
386 resp-specials = "]"
387
388 resp-text = ["[" resp-text-code "]" SP] text
389
390 resp-text-code = "ALERT" /
391 "BADCHARSET" [SP "(" astring *(SP astring) ")" ] /
392 capability-data / "PARSE" /
393 "PERMANENTFLAGS" SP "(" [flag-perm *(SP flag-perm)] ")" /
394 "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
395 "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
396 "UNSEEN" SP nz-number /
397 atom [SP 1*<any TEXT-CHAR except "]">]
398
399 search = "SEARCH" [SP "CHARSET" SP astring] 1*(SP search-key)
400 ; CHARSET argument to MUST be registered with IANA
401
402 search-key = "ALL" / "ANSWERED" / "BCC" SP astring /
403 "BEFORE" SP date / "BODY" SP astring /
404 "CC" SP astring / "DELETED" / "FLAGGED" /
405 "FROM" SP astring / "KEYWORD" SP flag-keyword / "NEW" /
406 "OLD" / "ON" SP date / "RECENT" / "SEEN" /
407 "SINCE" SP date / "SUBJECT" SP astring /
408 "TEXT" SP astring / "TO" SP astring /
409 "UNANSWERED" / "UNDELETED" / "UNFLAGGED" /
410 "UNKEYWORD" SP flag-keyword / "UNSEEN" /
411 ; Above this line were in [IMAP2]
412 "DRAFT" / "HEADER" SP header-fld-name SP astring /
413 "LARGER" SP number / "NOT" SP search-key /
414 "OR" SP search-key SP search-key /
415 "SENTBEFORE" SP date / "SENTON" SP date /
416 "SENTSINCE" SP date / "SMALLER" SP number /
417 "UID" SP set / "UNDRAFT" / set /
418 "(" search-key *(SP search-key) ")"
419
420 section = "[" [section-spec] "]"
421
422 section-msgtext = "HEADER" / "HEADER.FIELDS" [".NOT"] SP header-list /
423 "TEXT"
424 ; top-level or MESSAGE/RFC822 part
425
426 section-part = nz-number *("." nz-number)
427 ; body part nesting
428
429 section-spec = section-msgtext / (section-part ["." section-text])
430
431 section-text = section-msgtext / "MIME"
432 ; text other than actual body part (headers, etc.)
433
434 select = "SELECT" SP mailbox
435
436 sequence-num = nz-number / "*"
437 ; * is the largest number in use. For message
438 ; sequence numbers, it is the number of messages
439 ; in the mailbox. For unique identifiers, it is
440 ; the unique identifier of the last message in
441 ; the mailbox.
442
443 set = sequence-num / (sequence-num ":" sequence-num) /
444 (set "," set)
445 ; Identifies a set of messages. For message
446 ; sequence numbers, these are consecutive
447 ; numbers from 1 to the number of messages in
448 ; the mailbox
449 ; Comma delimits individual numbers, colon
450 ; delimits between two numbers inclusive.
451 ; Example: 2,4:7,9,12:* is 2,4,5,6,7,9,12,13,
452 ; 14,15 for a mailbox with 15 messages.
453
454
455 status = "STATUS" SP mailbox SP "(" status-att *(SP status-att) ")"
456
457 status-att = "MESSAGES" / "RECENT" / "UIDNEXT" / "UIDVALIDITY" /
458 "UNSEEN"
459
460 store = "STORE" SP set SP store-att-flags
461
462 store-att-flags = (["+" / "-"] "FLAGS" [".SILENT"]) SP
463 (flag-list / (flag *(SP flag)))
464
465 string = quoted / literal
466
467 subscribe = "SUBSCRIBE" SP mailbox
468
469 tag = 1*<any ASTRING-CHAR except "+">
470
471 text = 1*TEXT-CHAR
472
473 TEXT-CHAR = <any CHAR except CR and LF>
474
475 time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
476 ; Hours minutes seconds
477
478 uid = "UID" SP (copy / fetch / search / store)
479 ; Unique identifiers used instead of message
480 ; sequence numbers
481
482 uniqueid = nz-number
483 ; Strictly ascending
484
485 unsubscribe = "UNSUBSCRIBE" SP mailbox
486
487 userid = astring
488
489 x-command = "X" atom <experimental command arguments>
490
491 zone = ("+" / "-") 4DIGIT
492 ; Signed four-digit value of hhmm representing
493 ; hours and minutes east of Greenwich (that is,
494 ; the amount that the given time differs from
495 ; Universal Time). Subtracting the timezone
496 ; from the given time will give the UT form.
497 ; The Universal Time zone is "+0000".
498*/
499
500
501#ifndef MAILIMAP_TYPES_H
502
503#define MAILIMAP_TYPES_H
504
505#ifdef __cplusplus
506extern "C" {
507#endif
508
509#include <inttypes.h>
510#include <libetpan/mailstream.h>
511#include <libetpan/clist.h>
512
513
514/*
515 IMPORTANT NOTE:
516
517 All allocation functions will take as argument allocated data
518 and will store these data in the structure they will allocate.
519 Data should be persistant during all the use of the structure
520 and will be freed by the free function of the structure
521
522 allocation functions will return NULL on failure
523*/
524
525
526/*
527 mailimap_address represents a mail address
528
529 - personal_name is the name to display in an address
530 '"name"' in '"name" <address@domain>', should be allocated
531 with a malloc()
532
533 - source_route is the source-route information in the
534 mail address (RFC 822), should be allocated with a malloc()
535
536 - mailbox_name is the name of the mailbox 'address' in
537 '"name" <address@domain>', should be allocated with a malloc()
538
539 - host_name is the name of the host 'domain' in
540 '"name" <address@domain>', should be allocated with a malloc()
541
542 if mailbox_name is not NULL and host_name is NULL, this is the name
543 of a group, the next addresses in the list are elements of the group
544 until we reach an address with a NULL mailbox_name.
545*/
546
547struct mailimap_address {
548 char * ad_personal_name; /* can be NULL */
549 char * ad_source_route; /* can be NULL */
550 char * ad_mailbox_name; /* can be NULL */
551 char * ad_host_name; /* can be NULL */
552};
553
554
555struct mailimap_address *
556mailimap_address_new(char * ad_personal_name, char * ad_source_route,
557 char * ad_mailbox_name, char * ad_host_name);
558
559void mailimap_address_free(struct mailimap_address * addr);
560
561
562/* this is the type of MIME body parsed by IMAP server */
563
564enum {
565 MAILIMAP_BODY_ERROR,
566 MAILIMAP_BODY_1PART, /* single part */
567 MAILIMAP_BODY_MPART, /* multi-part */
568};
569
570/*
571 mailimap_body represent a MIME body parsed by IMAP server
572
573 - type is the type of the MIME part (single part or multipart)
574
575 - body_1part is defined if this is a single part
576
577 - body_mpart is defined if this is a multipart
578*/
579
580struct mailimap_body {
581 int bd_type;
582 /* can be MAILIMAP_BODY_1PART or MAILIMAP_BODY_MPART */
583 union {
584 struct mailimap_body_type_1part * bd_body_1part; /* can be NULL */
585 struct mailimap_body_type_mpart * bd_body_mpart; /* can be NULL */
586 } bd_data;
587};
588
589
590struct mailimap_body *
591mailimap_body_new(int bd_type,
592 struct mailimap_body_type_1part * bd_body_1part,
593 struct mailimap_body_type_mpart * bd_body_mpart);
594
595void mailimap_body_free(struct mailimap_body * body);
596
597
598
599/*
600 this is the type of MIME body extension
601*/
602
603enum {
604 MAILIMAP_BODY_EXTENSION_ERROR,
605 MAILIMAP_BODY_EXTENSION_NSTRING, /* string */
606 MAILIMAP_BODY_EXTENSION_NUMBER, /* number */
607 MAILIMAP_BODY_EXTENSION_LIST, /* list of
608 (struct mailimap_body_extension *) */
609};
610
611/*
612 mailimap_body_extension is a future extension header field value
613
614 - type is the type of the body extension (string, number or
615 list of extension)
616
617 - nstring is a string value if the type is string
618
619 - number is a integer value if the type is number
620
621 - list is a list of body extension if the type is a list
622*/
623
624struct mailimap_body_extension {
625 int ext_type;
626 /*
627 can be MAILIMAP_BODY_EXTENSION_NSTRING, MAILIMAP_BODY_EXTENSION_NUMBER
628 or MAILIMAP_BODY_EXTENSION_LIST
629 */
630 union {
631 char * ext_nstring; /* can be NULL */
632 uint32_t ext_number;
633 clist * ext_body_extension_list;
634 /* list of (struct mailimap_body_extension *) */
635 /* can be NULL */
636 } ext_data;
637};
638
639struct mailimap_body_extension *
640mailimap_body_extension_new(int ext_type, char * ext_nstring,
641 uint32_t ext_number,
642 clist * ext_body_extension_list);
643
644void mailimap_body_extension_free(struct mailimap_body_extension * be);
645
646
647/*
648 mailimap_body_ext_1part is the extended result part of a single part
649 bodystructure.
650
651 - body_md5 is the value of the Content-MD5 header field, should be
652 allocated with malloc()
653
654 - body_disposition is the value of the Content-Disposition header field
655
656 - body_language is the value of the Content-Language header field
657
658 - body_extension_list is the list of extension fields value.
659*/
660
661struct mailimap_body_ext_1part {
662 char * bd_md5; /* != NULL */
663 struct mailimap_body_fld_dsp * bd_disposition; /* can be NULL */
664 struct mailimap_body_fld_lang * bd_language; /* can be NULL */
665
666 clist * bd_extension_list; /* list of (struct mailimap_body_extension *) */
667 /* can be NULL */
668};
669
670struct mailimap_body_ext_1part *
671mailimap_body_ext_1part_new(char * bd_md5,
672 struct mailimap_body_fld_dsp * bd_disposition,
673 struct mailimap_body_fld_lang * bd_language,
674 clist * bd_extension_list);
675
676
677void
678mailimap_body_ext_1part_free(struct mailimap_body_ext_1part * body_ext_1part);
679
680
681/*
682 mailimap_body_ext_mpart is the extended result part of a multipart
683 bodystructure.
684
685 - body_parameter is the list of parameters of Content-Type header field
686
687 - body_disposition is the value of Content-Disposition header field
688
689 - body_language is the value of Content-Language header field
690
691 - body_extension_list is the list of extension fields value.
692*/
693
694struct mailimap_body_ext_mpart {
695 struct mailimap_body_fld_param * bd_parameter; /* != NULL */
696 struct mailimap_body_fld_dsp * bd_disposition; /* can be NULL */
697 struct mailimap_body_fld_lang * bd_language; /* can be NULL */
698 clist * bd_extension_list; /* list of (struct mailimap_body_extension *) */
699 /* can be NULL */
700};
701
702struct mailimap_body_ext_mpart *
703mailimap_body_ext_mpart_new(struct mailimap_body_fld_param * bd_parameter,
704 struct mailimap_body_fld_dsp * bd_disposition,
705 struct mailimap_body_fld_lang * bd_language,
706 clist * bd_extension_list);
707
708void
709mailimap_body_ext_mpart_free(struct mailimap_body_ext_mpart * body_ext_mpart);
710
711
712/*
713 mailimap_body_fields is the MIME fields of a MIME part.
714
715 - body_parameter is the list of parameters of Content-Type header field
716
717 - body_id is the value of Content-ID header field, should be allocated
718 with malloc()
719
720 - body_description is the value of Content-Description header field,
721 should be allocated with malloc()
722
723 - body_encoding is the value of Content-Transfer-Encoding header field
724
725 - body_disposition is the value of Content-Disposition header field
726
727 - body_size is the size of the MIME part
728*/
729
730struct mailimap_body_fields {
731 struct mailimap_body_fld_param * bd_parameter; /* != NULL */
732 char * bd_id; /* can be NULL */
733 char * bd_description; /* can be NULL */
734 struct mailimap_body_fld_enc * bd_encoding; /* != NULL */
735 uint32_t bd_size;
736};
737
738struct mailimap_body_fields *
739mailimap_body_fields_new(struct mailimap_body_fld_param * bd_parameter,
740 char * bd_id,
741 char * bd_description,
742 struct mailimap_body_fld_enc * bd_encoding,
743 uint32_t bd_size);
744
745void
746mailimap_body_fields_free(struct mailimap_body_fields * body_fields);
747
748
749
750/*
751 mailimap_body_fld_dsp is the parsed value of the Content-Disposition field
752
753 - disposition_type is the type of Content-Disposition
754 (usually attachment or inline), should be allocated with malloc()
755
756 - attributes is the list of Content-Disposition attributes
757*/
758
759struct mailimap_body_fld_dsp {
760 char * dsp_type; /* != NULL */
761 struct mailimap_body_fld_param * dsp_attributes; /* != NULL */
762};
763
764struct mailimap_body_fld_dsp *
765mailimap_body_fld_dsp_new(char * dsp_type,
766 struct mailimap_body_fld_param * dsp_attributes);
767
768void mailimap_body_fld_dsp_free(struct mailimap_body_fld_dsp * bfd);
769
770
771
772/* these are the different parsed values for Content-Transfer-Encoding */
773
774enum {
775 MAILIMAP_BODY_FLD_ENC_7BIT, /* 7bit */
776 MAILIMAP_BODY_FLD_ENC_8BIT, /* 8bit */
777 MAILIMAP_BODY_FLD_ENC_BINARY, /* binary */
778 MAILIMAP_BODY_FLD_ENC_BASE64, /* base64 */
779 MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE, /* quoted-printable */
780 MAILIMAP_BODY_FLD_ENC_OTHER, /* other */
781};
782
783/*
784 mailimap_body_fld_enc is a parsed value for Content-Transfer-Encoding
785
786 - type is the kind of Content-Transfer-Encoding, this can be
787 MAILIMAP_BODY_FLD_ENC_7BIT, MAILIMAP_BODY_FLD_ENC_8BIT,
788 MAILIMAP_BODY_FLD_ENC_BINARY, MAILIMAP_BODY_FLD_ENC_BASE64,
789 MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE or MAILIMAP_BODY_FLD_ENC_OTHER
790
791 - in case of MAILIMAP_BODY_FLD_ENC_OTHER, this value is defined,
792 should be allocated with malloc()
793*/
794
795struct mailimap_body_fld_enc {
796 int enc_type;
797 char * enc_value; /* can be NULL */
798};
799
800struct mailimap_body_fld_enc *
801mailimap_body_fld_enc_new(int enc_type, char * enc_value);
802
803void mailimap_body_fld_enc_free(struct mailimap_body_fld_enc * bfe);
804
805
806/* this is the type of Content-Language header field value */
807
808enum {
809 MAILIMAP_BODY_FLD_LANG_ERROR, /* error parse */
810 MAILIMAP_BODY_FLD_LANG_SINGLE, /* single value */
811 MAILIMAP_BODY_FLD_LANG_LIST /* list of values */
812};
813
814/*
815 mailimap_body_fld_lang is the parsed value of the Content-Language field
816
817 - type is the type of content, this can be MAILIMAP_BODY_FLD_LANG_SINGLE
818 if this is a single value or MAILIMAP_BODY_FLD_LANG_LIST if there are
819 several values
820
821 - single is the single value if the type is MAILIMAP_BODY_FLD_LANG_SINGLE,
822 should be allocated with malloc()
823
824 - list is the list of value if the type is MAILIMAP_BODY_FLD_LANG_LIST,
825 all elements of the list should be allocated with malloc()
826*/
827
828struct mailimap_body_fld_lang {
829 int lg_type;
830 union {
831 char * lg_single; /* can be NULL */
832 clist * lg_list; /* list of string (char *), can be NULL */
833 } lg_data;
834};
835
836struct mailimap_body_fld_lang *
837mailimap_body_fld_lang_new(int lg_type, char * lg_single, clist * lg_list);
838
839void
840mailimap_body_fld_lang_free(struct mailimap_body_fld_lang * fld_lang);
841
842
843
844/*
845 mailimap_single_body_fld_param is a body field parameter
846
847 - name is the name of the parameter, should be allocated with malloc()
848
849 - value is the value of the parameter, should be allocated with malloc()
850*/
851
852struct mailimap_single_body_fld_param {
853 char * pa_name; /* != NULL */
854 char * pa_value; /* != NULL */
855};
856
857struct mailimap_single_body_fld_param *
858mailimap_single_body_fld_param_new(char * pa_name, char * pa_value);
859
860void
861mailimap_single_body_fld_param_free(struct mailimap_single_body_fld_param * p);
862
863
864/*
865 mailmap_body_fld_param is a list of parameters
866
867 - list is the list of parameters.
868*/
869
870struct mailimap_body_fld_param {
871 clist * pa_list; /* list of (struct mailimap_single_body_fld_param *) */
872 /* != NULL */
873};
874
875struct mailimap_body_fld_param *
876mailimap_body_fld_param_new(clist * pa_list);
877
878void
879mailimap_body_fld_param_free(struct mailimap_body_fld_param * fld_param);
880
881
882/*
883 this is the kind of single part: a text part
884 (when Content-Type is text/xxx), a message part (when Content-Type is
885 message/rfc2822) or a basic part (others than multpart/xxx)
886*/
887
888enum {
889 MAILIMAP_BODY_TYPE_1PART_ERROR, /* parse error */
890 MAILIMAP_BODY_TYPE_1PART_BASIC, /* others then multipart/xxx */
891 MAILIMAP_BODY_TYPE_1PART_MSG, /* message/rfc2822 */
892 MAILIMAP_BODY_TYPE_1PART_TEXT /* text/xxx */
893};
894
895
896/*
897 mailimap_body_type_1part is
898
899 - type is the kind of single part, this can be
900 MAILIMAP_BODY_TYPE_1PART_BASIC, MAILIMAP_BODY_TYPE_1PART_MSG or
901 MAILIMAP_BODY_TYPE_1PART_TEXT.
902
903 - body_type_basic is the basic part when type is
904 MAILIMAP_BODY_TYPE_1PART_BASIC
905
906 - body_type_msg is the message part when type is
907 MAILIMAP_BODY_TYPE_1PART_MSG
908
909 - body_type_text is the text part when type is
910 MAILIMAP_BODY_TYPE_1PART_TEXT
911*/
912
913struct mailimap_body_type_1part {
914 int bd_type;
915 union {
916 struct mailimap_body_type_basic * bd_type_basic; /* can be NULL */
917 struct mailimap_body_type_msg * bd_type_msg; /* can be NULL */
918 struct mailimap_body_type_text * bd_type_text; /* can be NULL */
919 } bd_data;
920 struct mailimap_body_ext_1part * bd_ext_1part; /* can be NULL */
921};
922
923struct mailimap_body_type_1part *
924mailimap_body_type_1part_new(int bd_type,
925 struct mailimap_body_type_basic * bd_type_basic,
926 struct mailimap_body_type_msg * bd_type_msg,
927 struct mailimap_body_type_text * bd_type_text,
928 struct mailimap_body_ext_1part * bd_ext_1part);
929
930void
931mailimap_body_type_1part_free(struct mailimap_body_type_1part * bt1p);
932
933
934
935/*
936 mailimap_body_type_basic is a basic field (with Content-Type other
937 than multipart/xxx, message/rfc2822 and text/xxx
938
939 - media_basic will be the MIME type of the part
940
941 - body_fields will be the parsed fields of the MIME part
942*/
943
944struct mailimap_body_type_basic {
945 struct mailimap_media_basic * bd_media_basic; /* != NULL */
946 struct mailimap_body_fields * bd_fields; /* != NULL */
947};
948
949struct mailimap_body_type_basic *
950mailimap_body_type_basic_new(struct mailimap_media_basic * bd_media_basic,
951 struct mailimap_body_fields * bd_fields);
952
953void mailimap_body_type_basic_free(struct mailimap_body_type_basic *
954 body_type_basic);
955
956/*
957 mailimap_body_type_mpart is a MIME multipart.
958
959 - body_list is the list of sub-parts.
960
961 - media_subtype is the subtype of the multipart (for example
962 in multipart/alternative, this is "alternative")
963
964 - body_ext_mpart is the extended fields of the MIME multipart
965*/
966
967struct mailimap_body_type_mpart {
968 clist * bd_list; /* list of (struct mailimap_body *) */
969 /* != NULL */
970 char * bd_media_subtype; /* != NULL */
971 struct mailimap_body_ext_mpart * bd_ext_mpart; /* can be NULL */
972};
973
974struct mailimap_body_type_mpart *
975mailimap_body_type_mpart_new(clist * bd_list, char * bd_media_subtype,
976 struct mailimap_body_ext_mpart * bd_ext_mpart);
977
978void mailimap_body_type_mpart_free(struct mailimap_body_type_mpart *
979 body_type_mpart);
980
981/*
982 mailimap_body_type_msg is a MIME message part
983
984 - body_fields is the MIME fields of the MIME message part
985
986 - envelope is the list of parsed RFC 822 fields of the MIME message
987
988 - body is the sub-part of the message
989
990 - body_lines is the number of lines of the message part
991*/
992
993struct mailimap_body_type_msg {
994 struct mailimap_body_fields * bd_fields; /* != NULL */
995 struct mailimap_envelope * bd_envelope; /* != NULL */
996 struct mailimap_body * bd_body; /* != NULL */
997 uint32_t bd_lines;
998};
999
1000struct mailimap_body_type_msg *
1001mailimap_body_type_msg_new(struct mailimap_body_fields * bd_fields,
1002 struct mailimap_envelope * bd_envelope,
1003 struct mailimap_body * bd_body,
1004 uint32_t bd_lines);
1005
1006void
1007mailimap_body_type_msg_free(struct mailimap_body_type_msg * body_type_msg);
1008
1009
1010
1011/*
1012 mailimap_body_type_text is a single MIME part where Content-Type is text/xxx
1013
1014 - media-text is the subtype of the text part (for example, in "text/plain",
1015 this is "plain", should be allocated with malloc()
1016
1017 - body_fields is the MIME fields of the MIME message part
1018
1019 - body_lines is the number of lines of the message part
1020*/
1021
1022struct mailimap_body_type_text {
1023 char * bd_media_text; /* != NULL */
1024 struct mailimap_body_fields * bd_fields; /* != NULL */
1025 uint32_t bd_lines;
1026};
1027
1028struct mailimap_body_type_text *
1029mailimap_body_type_text_new(char * bd_media_text,
1030 struct mailimap_body_fields * bd_fields,
1031 uint32_t bd_lines);
1032
1033void
1034mailimap_body_type_text_free(struct mailimap_body_type_text * body_type_text);
1035
1036
1037
1038/* this is the type of capability field */
1039
1040enum {
1041 MAILIMAP_CAPABILITY_AUTH_TYPE, /* when the capability is an
1042 authentication type */
1043 MAILIMAP_CAPABILITY_NAME, /* other type of capability */
1044};
1045
1046/*
1047 mailimap_capability is a capability of the IMAP server
1048
1049 - type is the type of capability, this is either a authentication type
1050 (MAILIMAP_CAPABILITY_AUTH_TYPE) or an other type of capability
1051 (MAILIMAP_CAPABILITY_NAME)
1052
1053 - auth_type is a type of authentication "name" in "AUTH=name",
1054 auth_type can be for example "PLAIN", when this is an authentication type,
1055 should be allocated with malloc()
1056
1057 - name is a type of capability when this is not an authentication type,
1058 should be allocated with malloc()
1059*/
1060
1061struct mailimap_capability {
1062 int cap_type;
1063 union {
1064 char * cap_auth_type; /* can be NULL */
1065 char * cap_name; /* can be NULL */
1066 } cap_data;
1067};
1068
1069struct mailimap_capability *
1070mailimap_capability_new(int cap_type, char * cap_auth_type, char * cap_name);
1071
1072void mailimap_capability_free(struct mailimap_capability * c);
1073
1074
1075
1076
1077/*
1078 mailimap_capability_data is a list of capability
1079
1080 - list is the list of capability
1081*/
1082
1083struct mailimap_capability_data {
1084 clist * cap_list; /* list of (struct mailimap_capability *), != NULL */
1085};
1086
1087struct mailimap_capability_data *
1088mailimap_capability_data_new(clist * cap_list);
1089
1090void
1091mailimap_capability_data_free(struct mailimap_capability_data * cap_data);
1092
1093
1094
1095/* this is the type of continue request data */
1096
1097enum {
1098 MAILIMAP_CONTINUE_REQ_ERROR, /* on parse error */
1099 MAILIMAP_CONTINUE_REQ_TEXT, /* when data is a text response */
1100 MAILIMAP_CONTINUE_REQ_BASE64, /* when data is a base64 response */
1101};
1102
1103/*
1104 mailimap_continue_req is a continue request (a response prefixed by "+")
1105
1106 - type is the type of continue request response
1107 MAILIMAP_CONTINUE_REQ_TEXT (when information data is text),
1108 MAILIMAP_CONTINUE_REQ_BASE64 (when information data is base64)
1109
1110 - text is the information of type text in case of text data
1111
1112 - base64 is base64 encoded data in the other case, should be allocated
1113 with malloc()
1114*/
1115
1116struct mailimap_continue_req {
1117 int cr_type;
1118 union {
1119 struct mailimap_resp_text * cr_text; /* can be NULL */
1120 char * cr_base64; /* can be NULL */
1121 } cr_data;
1122};
1123
1124struct mailimap_continue_req *
1125mailimap_continue_req_new(int cr_type, struct mailimap_resp_text * cr_text,
1126 char * cr_base64);
1127
1128void mailimap_continue_req_free(struct mailimap_continue_req * cont_req);
1129
1130
1131/*
1132 mailimap_date_time is a date
1133
1134 - day is the day of month (1 to 31)
1135
1136 - month (1 to 12)
1137
1138 - year (4 digits)
1139
1140 - hour (0 to 23)
1141
1142 - min (0 to 59)
1143
1144 - sec (0 to 59)
1145
1146 - zone (this is the decimal value that we can read, for example:
1147 for "-0200", the value is -200)
1148*/
1149
1150struct mailimap_date_time {
1151 int dt_day;
1152 int dt_month;
1153 int dt_year;
1154 int dt_hour;
1155 int dt_min;
1156 int dt_sec;
1157 int dt_zone;
1158};
1159
1160struct mailimap_date_time *
1161mailimap_date_time_new(int dt_day, int dt_month, int dt_year, int dt_hour,
1162 int dt_min, int dt_sec, int dt_zone);
1163
1164void mailimap_date_time_free(struct mailimap_date_time * date_time);
1165
1166
1167
1168/*
1169 mailimap_envelope is the list of fields that can be parsed by
1170 the IMAP server.
1171
1172 - date is the (non-parsed) content of the "Date" header field,
1173 should be allocated with malloc()
1174
1175 - subject is the subject of the message, should be allocated with
1176 malloc()
1177
1178 - sender is the the parsed content of the "Sender" field
1179
1180 - reply-to is the parsed content of the "Reply-To" field
1181
1182 - to is the parsed content of the "To" field
1183
1184 - cc is the parsed content of the "Cc" field
1185
1186 - bcc is the parsed content of the "Bcc" field
1187
1188 - in_reply_to is the content of the "In-Reply-To" field,
1189 should be allocated with malloc()
1190
1191 - message_id is the content of the "Message-ID" field,
1192 should be allocated with malloc()
1193*/
1194
1195struct mailimap_envelope {
1196 char * env_date; /* can be NULL */
1197 char * env_subject; /* can be NULL */
1198 struct mailimap_env_from * env_from; /* can be NULL */
1199 struct mailimap_env_sender * env_sender; /* can be NULL */
1200 struct mailimap_env_reply_to * env_reply_to; /* can be NULL */
1201 struct mailimap_env_to * env_to; /* can be NULL */
1202 struct mailimap_env_cc * env_cc; /* can be NULL */
1203 struct mailimap_env_bcc * env_bcc; /* can be NULL */
1204 char * env_in_reply_to; /* can be NULL */
1205 char * env_message_id; /* can be NULL */
1206};
1207
1208struct mailimap_envelope *
1209mailimap_envelope_new(char * env_date, char * env_subject,
1210 struct mailimap_env_from * env_from,
1211 struct mailimap_env_sender * env_sender,
1212 struct mailimap_env_reply_to * env_reply_to,
1213 struct mailimap_env_to * env_to,
1214 struct mailimap_env_cc* env_cc,
1215 struct mailimap_env_bcc * env_bcc,
1216 char * env_in_reply_to, char * env_message_id);
1217
1218void mailimap_envelope_free(struct mailimap_envelope * env);
1219
1220
1221
1222/*
1223 mailimap_env_bcc is the parsed "Bcc" field
1224
1225 - list is the list of addresses
1226*/
1227
1228struct mailimap_env_bcc {
1229 clist * bcc_list; /* list of (struct mailimap_address *), != NULL */
1230};
1231
1232struct mailimap_env_bcc * mailimap_env_bcc_new(clist * bcc_list);
1233
1234void mailimap_env_bcc_free(struct mailimap_env_bcc * env_bcc);
1235
1236
1237/*
1238 mailimap_env_cc is the parsed "Cc" field
1239
1240 - list is the list of addresses
1241*/
1242
1243struct mailimap_env_cc {
1244 clist * cc_list; /* list of (struct mailimap_address *), != NULL */
1245};
1246
1247struct mailimap_env_cc * mailimap_env_cc_new(clist * cc_list);
1248
1249void mailimap_env_cc_free(struct mailimap_env_cc * env_cc);
1250
1251
1252
1253/*
1254 mailimap_env_from is the parsed "From" field
1255
1256 - list is the list of addresses
1257*/
1258
1259struct mailimap_env_from {
1260 clist * frm_list; /* list of (struct mailimap_address *) */
1261 /* != NULL */
1262};
1263
1264struct mailimap_env_from * mailimap_env_from_new(clist * frm_list);
1265
1266void mailimap_env_from_free(struct mailimap_env_from * env_from);
1267
1268
1269
1270/*
1271 mailimap_env_reply_to is the parsed "Reply-To" field
1272
1273 - list is the list of addresses
1274*/
1275
1276struct mailimap_env_reply_to {
1277 clist * rt_list; /* list of (struct mailimap_address *), != NULL */
1278};
1279
1280struct mailimap_env_reply_to * mailimap_env_reply_to_new(clist * rt_list);
1281
1282void
1283mailimap_env_reply_to_free(struct mailimap_env_reply_to * env_reply_to);
1284
1285
1286
1287/*
1288 mailimap_env_sender is the parsed "Sender" field
1289
1290 - list is the list of addresses
1291*/
1292
1293struct mailimap_env_sender {
1294 clist * snd_list; /* list of (struct mailimap_address *), != NULL */
1295};
1296
1297struct mailimap_env_sender * mailimap_env_sender_new(clist * snd_list);
1298
1299void mailimap_env_sender_free(struct mailimap_env_sender * env_sender);
1300
1301
1302
1303/*
1304 mailimap_env_to is the parsed "To" field
1305
1306 - list is the list of addresses
1307*/
1308
1309struct mailimap_env_to {
1310 clist * to_list; /* list of (struct mailimap_address *), != NULL */
1311};
1312
1313struct mailimap_env_to * mailimap_env_to_new(clist * to_list);
1314
1315void mailimap_env_to_free(struct mailimap_env_to * env_to);
1316
1317
1318/* this is the type of flag */
1319
1320enum {
1321 MAILIMAP_FLAG_ANSWERED, /* \Answered flag */
1322 MAILIMAP_FLAG_FLAGGED, /* \Flagged flag */
1323 MAILIMAP_FLAG_DELETED, /* \Deleted flag */
1324 MAILIMAP_FLAG_SEEN, /* \Seen flag */
1325 MAILIMAP_FLAG_DRAFT, /* \Draft flag */
1326 MAILIMAP_FLAG_KEYWORD, /* keyword flag */
1327 MAILIMAP_FLAG_EXTENSION, /* \extension flag */
1328};
1329
1330
1331/*
1332 mailimap_flag is a message flag (that we can associate with a message)
1333
1334 - type is the type of the flag, MAILIMAP_FLAG_XXX
1335
1336 - keyword is the flag when the flag is of keyword type,
1337 should be allocated with malloc()
1338
1339 - extension is the flag when the flag is of extension type, should be
1340 allocated with malloc()
1341*/
1342
1343struct mailimap_flag {
1344 int fl_type;
1345 union {
1346 char * fl_keyword; /* can be NULL */
1347 char * fl_extension; /* can be NULL */
1348 } fl_data;
1349};
1350
1351struct mailimap_flag * mailimap_flag_new(int fl_type,
1352 char * fl_keyword, char * fl_extension);
1353
1354void mailimap_flag_free(struct mailimap_flag * f);
1355
1356
1357
1358
1359/* this is the type of flag */
1360
1361enum {
1362 MAILIMAP_FLAG_FETCH_ERROR, /* on parse error */
1363 MAILIMAP_FLAG_FETCH_RECENT, /* \Recent flag */
1364 MAILIMAP_FLAG_FETCH_OTHER, /* other type of flag */
1365};
1366
1367/*
1368 mailimap_flag_fetch is a message flag (when we fetch it)
1369
1370 - type is the type of flag fetch
1371
1372 - flag is the flag when this is not a \Recent flag
1373*/
1374
1375struct mailimap_flag_fetch {
1376 int fl_type;
1377 struct mailimap_flag * fl_flag; /* can be NULL */
1378};
1379
1380struct mailimap_flag_fetch *
1381mailimap_flag_fetch_new(int fl_type, struct mailimap_flag * fl_flag);
1382
1383void mailimap_flag_fetch_free(struct mailimap_flag_fetch * flag_fetch);
1384
1385
1386
1387
1388/* this is the type of flag */
1389
1390enum {
1391 MAILIMAP_FLAG_PERM_ERROR, /* on parse error */
1392 MAILIMAP_FLAG_PERM_FLAG, /* to specify that usual flags can be changed */
1393 MAILIMAP_FLAG_PERM_ALL /* to specify that new flags can be created */
1394};
1395
1396
1397/*
1398 mailimap_flag_perm is a flag returned in case of PERMANENTFLAGS response
1399
1400 - type is the type of returned PERMANENTFLAGS, it can be
1401 MAILIMAP_FLAG_PERM_FLAG (the given flag can be changed permanently) or
1402 MAILIMAP_FLAG_PERM_ALL (new flags can be created)
1403
1404 - flag is the given flag when type is MAILIMAP_FLAG_PERM_FLAG
1405*/
1406
1407struct mailimap_flag_perm {
1408 int fl_type;
1409 struct mailimap_flag * fl_flag; /* can be NULL */
1410};
1411
1412struct mailimap_flag_perm *
1413mailimap_flag_perm_new(int fl_type, struct mailimap_flag * fl_flag);
1414
1415void mailimap_flag_perm_free(struct mailimap_flag_perm * flag_perm);
1416
1417
1418/*
1419 mailimap_flag_list is a list of flags
1420
1421 - list is a list of flags
1422*/
1423
1424struct mailimap_flag_list {
1425 clist * fl_list; /* list of (struct mailimap_flag *), != NULL */
1426};
1427
1428struct mailimap_flag_list *
1429mailimap_flag_list_new(clist * fl_list);
1430
1431void mailimap_flag_list_free(struct mailimap_flag_list * flag_list);
1432
1433
1434
1435
1436/* this is the type of greeting response */
1437
1438enum {
1439 MAILIMAP_GREETING_RESP_COND_ERROR, /* on parse error */
1440 MAILIMAP_GREETING_RESP_COND_AUTH, /* when connection is accepted */
1441 MAILIMAP_GREETING_RESP_COND_BYE, /* when connection is refused */
1442};
1443
1444/*
1445 mailimap_greeting is the response returned on connection
1446
1447 - type is the type of response on connection, either
1448 MAILIMAP_GREETING_RESP_COND_AUTH if connection is accepted or
1449 MAIMIMAP_GREETING_RESP_COND_BYE if connection is refused
1450*/
1451
1452struct mailimap_greeting {
1453 int gr_type;
1454 union {
1455 struct mailimap_resp_cond_auth * gr_auth; /* can be NULL */
1456 struct mailimap_resp_cond_bye * gr_bye; /* can be NULL */
1457 } gr_data;
1458};
1459
1460struct mailimap_greeting *
1461mailimap_greeting_new(int gr_type,
1462 struct mailimap_resp_cond_auth * gr_auth,
1463 struct mailimap_resp_cond_bye * gr_bye);
1464
1465void mailimap_greeting_free(struct mailimap_greeting * greeting);
1466
1467
1468/*
1469 mailimap_header_list is a list of headers that can be specified when
1470 we want to fetch fields
1471
1472 - list is a list of header names, each header name should be allocated
1473 with malloc()
1474*/
1475
1476struct mailimap_header_list {
1477 clist * hdr_list; /* list of astring (char *), != NULL */
1478};
1479
1480struct mailimap_header_list *
1481mailimap_header_list_new(clist * hdr_list);
1482
1483void
1484mailimap_header_list_free(struct mailimap_header_list * header_list);
1485
1486
1487
1488/* this is the type of mailbox STATUS that can be returned */
1489
1490enum {
1491 MAILIMAP_STATUS_ATT_MESSAGES, /* when requesting the number of
1492 messages */
1493 MAILIMAP_STATUS_ATT_RECENT, /* when requesting the number of
1494 recent messages */
1495 MAILIMAP_STATUS_ATT_UIDNEXT, /* when requesting the next unique
1496 identifier */
1497 MAILIMAP_STATUS_ATT_UIDVALIDITY, /* when requesting the validity of
1498 message unique identifiers*/
1499 MAILIMAP_STATUS_ATT_UNSEEN, /* when requesting the number of
1500 unseen messages */
1501};
1502
1503/*
1504 mailimap_status_info is a returned information when a STATUS of
1505 a mailbox is requested
1506
1507 - att is the type of mailbox STATUS, the value can be
1508 MAILIMAP_STATUS_ATT_MESSAGES, MAILIMAP_STATUS_ATT_RECENT,
1509 MAILIMAP_STATUS_ATT_UIDNEXT, MAILIMAP_STATUS_ATT_UIDVALIDITY or
1510 MAILIMAP_STATUS_ATT_UNSEEN
1511
1512 - value is the value of the given information
1513*/
1514
1515struct mailimap_status_info {
1516 int st_att;
1517 uint32_t st_value;
1518};
1519
1520struct mailimap_status_info *
1521mailimap_status_info_new(int st_att, uint32_t st_value);
1522
1523void mailimap_status_info_free(struct mailimap_status_info * info);
1524
1525
1526
1527/*
1528 mailimap_mailbox_data_status is the list of information returned
1529 when a STATUS of a mailbox is requested
1530
1531 - mailbox is the name of the mailbox, should be allocated with malloc()
1532
1533 - status_info_list is the list of information returned
1534*/
1535
1536struct mailimap_mailbox_data_status {
1537 char * st_mailbox;
1538 clist * st_info_list; /* list of (struct mailimap_status_info *) */
1539 /* can be NULL */
1540};
1541
1542struct mailimap_mailbox_data_status *
1543mailimap_mailbox_data_status_new(char * st_mailbox,
1544 clist * st_info_list);
1545
1546void
1547mailimap_mailbox_data_status_free(struct mailimap_mailbox_data_status * info);
1548
1549
1550
1551/* this is the type of mailbox information that is returned */
1552
1553enum {
1554 MAILIMAP_MAILBOX_DATA_ERROR, /* on parse error */
1555 MAILIMAP_MAILBOX_DATA_FLAGS, /* flag that are applicable to the mailbox */
1556 MAILIMAP_MAILBOX_DATA_LIST, /* this is a mailbox in the list of mailboxes
1557 returned on LIST command*/
1558 MAILIMAP_MAILBOX_DATA_LSUB, /* this is a mailbox in the list of
1559 subscribed mailboxes returned on LSUB
1560 command */
1561 MAILIMAP_MAILBOX_DATA_SEARCH, /* this is a list of messages numbers or
1562 unique identifiers returned
1563 on a SEARCH command*/
1564 MAILIMAP_MAILBOX_DATA_STATUS, /* this is the list of information returned
1565 on a STATUS command */
1566 MAILIMAP_MAILBOX_DATA_EXISTS, /* this is the number of messages in the
1567 mailbox */
1568 MAILIMAP_MAILBOX_DATA_RECENT, /* this is the number of recent messages
1569 in the mailbox */
1570};
1571
1572/*
1573 mailimap_mailbox_data is an information related to a mailbox
1574
1575 - type is the type of mailbox_data that is filled, the value of this field
1576 can be MAILIMAP_MAILBOX_DATA_FLAGS, MAILIMAP_MAILBOX_DATA_LIST,
1577 MAILIMAP_MAILBOX_DATA_LSUB, MAILIMAP_MAILBOX_DATA_SEARCH,
1578 MAILIMAP_MAILBOX_DATA_STATUS, MAILIMAP_MAILBOX_DATA_EXISTS
1579 or MAILIMAP_MAILBOX_DATA_RECENT.
1580
1581 - flags is the flags that are applicable to the mailbox when
1582 type is MAILIMAP_MAILBOX_DATA_FLAGS
1583
1584 - list is a mailbox in the list of mailboxes returned on LIST command
1585 when type is MAILIMAP_MAILBOX_DATA_LIST
1586
1587 - lsub is a mailbox in the list of subscribed mailboxes returned on
1588 LSUB command when type is MAILIMAP_MAILBOX_DATA_LSUB
1589
1590 - search is a list of messages numbers or unique identifiers returned
1591 on SEARCH command when type MAILIMAP_MAILBOX_DATA_SEARCH, each element
1592 should be allocated with malloc()
1593
1594 - status is a list of information returned on STATUS command when
1595 type is MAILIMAP_MAILBOX_DATA_STATUS
1596
1597 - exists is the number of messages in the mailbox when type
1598 is MAILIMAP_MAILBOX_DATA_EXISTS
1599
1600 - recent is the number of recent messages in the mailbox when type
1601 is MAILIMAP_MAILBOX_DATA_RECENT
1602*/
1603
1604struct mailimap_mailbox_data {
1605 int mbd_type;
1606 union {
1607 struct mailimap_flag_list * mbd_flags; /* can be NULL */
1608 struct mailimap_mailbox_list * mbd_list; /* can be NULL */
1609 struct mailimap_mailbox_list * mbd_lsub; /* can be NULL */
1610 clist * mbd_search; /* list of nz-number (uint32_t *), can be NULL */
1611 struct mailimap_mailbox_data_status * mbd_status; /* can be NULL */
1612 uint32_t mbd_exists;
1613 uint32_t mbd_recent;
1614 } mbd_data;
1615};
1616
1617struct mailimap_mailbox_data *
1618mailimap_mailbox_data_new(int mbd_type, struct mailimap_flag_list * mbd_flags,
1619 struct mailimap_mailbox_list * mbd_list,
1620 struct mailimap_mailbox_list * mbd_lsub,
1621 clist * mbd_search,
1622 struct mailimap_mailbox_data_status * mbd_status,
1623 uint32_t mbd_exists,
1624 uint32_t mbd_recent);
1625
1626void
1627mailimap_mailbox_data_free(struct mailimap_mailbox_data * mb_data);
1628
1629
1630
1631/* this is the type of mailbox flags */
1632
1633enum {
1634 MAILIMAP_MBX_LIST_FLAGS_SFLAG, /* mailbox single flag - a flag in
1635 {\NoSelect, \Marked, \Unmarked} */
1636 MAILIMAP_MBX_LIST_FLAGS_NO_SFLAG, /* mailbox other flag - mailbox flag
1637 other than \NoSelect \Marked and
1638 \Unmarked) */
1639};
1640
1641/* this is a single flag type */
1642
1643enum {
1644 MAILIMAP_MBX_LIST_SFLAG_ERROR,
1645 MAILIMAP_MBX_LIST_SFLAG_MARKED,
1646 MAILIMAP_MBX_LIST_SFLAG_NOSELECT,
1647 MAILIMAP_MBX_LIST_SFLAG_UNMARKED
1648};
1649
1650/*
1651 mailimap_mbx_list_flags is a mailbox flag
1652
1653 - type is the type of mailbox flag, it can be MAILIMAP_MBX_LIST_FLAGS_SFLAG,
1654 or MAILIMAP_MBX_LIST_FLAGS_NO_SFLAG.
1655
1656 - oflags is a list of "mailbox other flag"
1657
1658 - sflag is a mailbox single flag
1659*/
1660
1661struct mailimap_mbx_list_flags {
1662 int mbf_type;
1663 clist * mbf_oflags; /* list of
1664 (struct mailimap_mbx_list_oflag *), != NULL */
1665 int mbf_sflag;
1666};
1667
1668struct mailimap_mbx_list_flags *
1669mailimap_mbx_list_flags_new(int mbf_type,
1670 clist * mbf_oflags, int mbf_sflag);
1671
1672void
1673mailimap_mbx_list_flags_free(struct mailimap_mbx_list_flags * mbx_list_flags);
1674
1675
1676
1677/* this is the type of the mailbox other flag */
1678
1679enum {
1680 MAILIMAP_MBX_LIST_OFLAG_ERROR, /* on parse error */
1681 MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS, /* \NoInferior flag */
1682 MAILIMAP_MBX_LIST_OFLAG_FLAG_EXT /* other flag */
1683};
1684
1685/*
1686 mailimap_mbx_list_oflag is a mailbox other flag
1687
1688 - type can be MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS when this is
1689 a \NoInferior flag or MAILIMAP_MBX_LIST_OFLAG_FLAG_EXT
1690
1691 - flag_ext is set when MAILIMAP_MBX_LIST_OFLAG_FLAG_EXT and is
1692 an extension flag, should be allocated with malloc()
1693*/
1694
1695struct mailimap_mbx_list_oflag {
1696 int of_type;
1697 char * of_flag_ext; /* can be NULL */
1698};
1699
1700struct mailimap_mbx_list_oflag *
1701mailimap_mbx_list_oflag_new(int of_type, char * of_flag_ext);
1702
1703void
1704mailimap_mbx_list_oflag_free(struct mailimap_mbx_list_oflag * oflag);
1705
1706
1707
1708/*
1709 mailimap_mailbox_list is a list of mailbox flags
1710
1711 - mb_flag is a list of mailbox flags
1712
1713 - delimiter is the delimiter of the mailbox path
1714
1715 - mb is the name of the mailbox, should be allocated with malloc()
1716*/
1717
1718struct mailimap_mailbox_list {
1719 struct mailimap_mbx_list_flags * mb_flag; /* can be NULL */
1720 char mb_delimiter;
1721 char * mb_name; /* != NULL */
1722};
1723
1724struct mailimap_mailbox_list *
1725mailimap_mailbox_list_new(struct mailimap_mbx_list_flags * mbx_flags,
1726 char mb_delimiter, char * mb_name);
1727
1728void
1729mailimap_mailbox_list_free(struct mailimap_mailbox_list * mb_list);
1730
1731
1732
1733/* this is the MIME type */
1734
1735enum {
1736 MAILIMAP_MEDIA_BASIC_APPLICATION, /* application/xxx */
1737 MAILIMAP_MEDIA_BASIC_AUDIO, /* audio/xxx */
1738 MAILIMAP_MEDIA_BASIC_IMAGE, /* image/xxx */
1739 MAILIMAP_MEDIA_BASIC_MESSAGE, /* message/xxx */
1740 MAILIMAP_MEDIA_BASIC_VIDEO, /* video/xxx */
1741 MAILIMAP_MEDIA_BASIC_OTHER, /* for all other cases */
1742};
1743
1744
1745/*
1746 mailimap_media_basic is the MIME type
1747
1748 - type can be MAILIMAP_MEDIA_BASIC_APPLICATION, MAILIMAP_MEDIA_BASIC_AUDIO,
1749 MAILIMAP_MEDIA_BASIC_IMAGE, MAILIMAP_MEDIA_BASIC_MESSAGE,
1750 MAILIMAP_MEDIA_BASIC_VIDEO or MAILIMAP_MEDIA_BASIC_OTHER
1751
1752 - basic_type is defined when type is MAILIMAP_MEDIA_BASIC_OTHER, should
1753 be allocated with malloc()
1754
1755 - subtype is the subtype of the MIME type, for example, this is
1756 "data" in "application/data", should be allocated with malloc()
1757*/
1758
1759struct mailimap_media_basic {
1760 int med_type;
1761 char * med_basic_type; /* can be NULL */
1762 char * med_subtype; /* != NULL */
1763};
1764
1765struct mailimap_media_basic *
1766mailimap_media_basic_new(int med_type,
1767 char * med_basic_type, char * med_subtype);
1768
1769void
1770mailimap_media_basic_free(struct mailimap_media_basic * media_basic);
1771
1772
1773
1774/* this is the type of message data */
1775
1776enum {
1777 MAILIMAP_MESSAGE_DATA_ERROR,
1778 MAILIMAP_MESSAGE_DATA_EXPUNGE,
1779 MAILIMAP_MESSAGE_DATA_FETCH
1780};
1781
1782/*
1783 mailimap_message_data is an information related to a message
1784
1785 - number is the number or the unique identifier of the message
1786
1787 - type is the type of information, this value can be
1788 MAILIMAP_MESSAGE_DATA_EXPUNGE or MAILIMAP_MESSAGE_DATA_FETCH
1789
1790 - msg_att is the message data
1791*/
1792
1793struct mailimap_message_data {
1794 uint32_t mdt_number;
1795 int mdt_type;
1796 struct mailimap_msg_att * mdt_msg_att; /* can be NULL */
1797 /* if type = EXPUNGE, can be NULL */
1798};
1799
1800struct mailimap_message_data *
1801mailimap_message_data_new(uint32_t mdt_number, int mdt_type,
1802 struct mailimap_msg_att * mdt_msg_att);
1803
1804void
1805mailimap_message_data_free(struct mailimap_message_data * msg_data);
1806
1807
1808
1809/* this the type of the message attributes */
1810
1811enum {
1812 MAILIMAP_MSG_ATT_ITEM_ERROR, /* on parse error */
1813 MAILIMAP_MSG_ATT_ITEM_DYNAMIC, /* dynamic message attributes (flags) */
1814 MAILIMAP_MSG_ATT_ITEM_STATIC, /* static messages attributes
1815 (message content) */
1816};
1817
1818/*
1819 mailimap_msg_att_item is a message attribute
1820
1821 - type is the type of message attribute, the value can be
1822 MAILIMAP_MSG_ATT_ITEM_DYNAMIC or MAILIMAP_MSG_ATT_ITEM_STATIC
1823
1824 - msg_att_dyn is a dynamic message attribute when type is
1825 MAILIMAP_MSG_ATT_ITEM_DYNAMIC
1826
1827 - msg_att_static is a static message attribute when type is
1828 MAILIMAP_MSG_ATT_ITEM_STATIC
1829*/
1830
1831struct mailimap_msg_att_item {
1832 int att_type;
1833 union {
1834 struct mailimap_msg_att_dynamic * att_dyn; /* can be NULL */
1835 struct mailimap_msg_att_static * att_static; /* can be NULL */
1836 } att_data;
1837};
1838
1839struct mailimap_msg_att_item *
1840mailimap_msg_att_item_new(int att_type,
1841 struct mailimap_msg_att_dynamic * att_dyn,
1842 struct mailimap_msg_att_static * att_static);
1843
1844void
1845mailimap_msg_att_item_free(struct mailimap_msg_att_item * item);
1846
1847
1848/*
1849 mailimap_msg_att is a list of attributes
1850
1851 - list is a list of message attributes
1852
1853 - number is the message number or unique identifier, this field
1854 has been added for implementation purpose
1855*/
1856
1857struct mailimap_msg_att {
1858 clist * att_list; /* list of (struct mailimap_msg_att_item *) */
1859 /* != NULL */
1860 uint32_t att_number; /* extra field to store the message number,
1861 used for mailimap */
1862};
1863
1864struct mailimap_msg_att * mailimap_msg_att_new(clist * att_list);
1865
1866void mailimap_msg_att_free(struct mailimap_msg_att * msg_att);
1867
1868
1869/*
1870 mailimap_msg_att_dynamic is a dynamic message attribute
1871
1872 - list is a list of flags (that have been fetched)
1873*/
1874
1875struct mailimap_msg_att_dynamic {
1876 clist * att_list; /* list of (struct mailimap_flag_fetch *) */
1877 /* can be NULL */
1878};
1879
1880struct mailimap_msg_att_dynamic *
1881mailimap_msg_att_dynamic_new(clist * att_list);
1882
1883void
1884mailimap_msg_att_dynamic_free(struct mailimap_msg_att_dynamic * msg_att_dyn);
1885
1886
1887
1888/*
1889 mailimap_msg_att_body_section is a MIME part content
1890
1891 - section is the location of the MIME part in the message
1892
1893 - origin_octet is the offset of the requested part of the MIME part
1894
1895 - body_part is the content or partial content of the MIME part,
1896 should be allocated through a MMAPString
1897
1898 - length is the size of the content
1899*/
1900
1901struct mailimap_msg_att_body_section {
1902 struct mailimap_section * sec_section; /* != NULL */
1903 uint32_t sec_origin_octet;
1904 char * sec_body_part; /* can be NULL */
1905 size_t sec_length;
1906};
1907
1908struct mailimap_msg_att_body_section *
1909mailimap_msg_att_body_section_new(struct mailimap_section * section,
1910 uint32_t sec_origin_octet,
1911 char * sec_body_part,
1912 size_t sec_length);
1913
1914void
1915mailimap_msg_att_body_section_free(struct mailimap_msg_att_body_section *
1916 msg_att_body_section);
1917
1918
1919
1920/*
1921 this is the type of static message attribute
1922*/
1923
1924enum {
1925 MAILIMAP_MSG_ATT_ERROR, /* on parse error */
1926 MAILIMAP_MSG_ATT_ENVELOPE, /* this is the fields that can be
1927 parsed by the server */
1928 MAILIMAP_MSG_ATT_INTERNALDATE, /* this is the message date kept
1929 by the server */
1930 MAILIMAP_MSG_ATT_RFC822, /* this is the message content
1931 (header and body) */
1932 MAILIMAP_MSG_ATT_RFC822_HEADER, /* this is the message header */
1933 MAILIMAP_MSG_ATT_RFC822_TEXT, /* this is the message text part */
1934 MAILIMAP_MSG_ATT_RFC822_SIZE, /* this is the size of the message content */
1935 MAILIMAP_MSG_ATT_BODY, /* this is the MIME description of
1936 the message */
1937 MAILIMAP_MSG_ATT_BODYSTRUCTURE, /* this is the MIME description of the
1938 message with additional information */
1939 MAILIMAP_MSG_ATT_BODY_SECTION, /* this is a MIME part content */
1940 MAILIMAP_MSG_ATT_UID, /* this is the message unique identifier */
1941};
1942
1943/*
1944 mailimap_msg_att_static is a given part of the message
1945
1946 - type is the type of the static message attribute, the value can be
1947 MAILIMAP_MSG_ATT_ENVELOPE, MAILIMAP_MSG_ATT_INTERNALDATE,
1948 MAILIMAP_MSG_ATT_RFC822, MAILIMAP_MSG_ATT_RFC822_HEADER,
1949 MAILIMAP_MSG_ATT_RFC822_TEXT, MAILIMAP_MSG_ATT_RFC822_SIZE,
1950 MAILIMAP_MSG_ATT_BODY, MAILIMAP_MSG_ATT_BODYSTRUCTURE,
1951 MAILIMAP_MSG_ATT_BODY_SECTION, MAILIMAP_MSG_ATT_UID
1952
1953 - env is the headers parsed by the server if type is
1954 MAILIMAP_MSG_ATT_ENVELOPE
1955
1956 - internal_date is the date of message kept by the server if type is
1957 MAILIMAP_MSG_ATT_INTERNALDATE
1958
1959 - rfc822 is the message content if type is MAILIMAP_MSG_ATT_RFC822,
1960 should be allocated through a MMAPString
1961
1962 - rfc822_header is the message header if type is
1963 MAILIMAP_MSG_ATT_RFC822_HEADER, should be allocated through a MMAPString
1964
1965 - rfc822_text is the message text part if type is
1966 MAILIMAP_MSG_ATT_RFC822_TEXT, should be allocated through a MMAPString
1967
1968 - rfc822_size is the message size if type is MAILIMAP_MSG_ATT_SIZE
1969
1970 - body is the MIME description of the message
1971
1972 - bodystructure is the MIME description of the message with additional
1973 information
1974
1975 - body_section is a MIME part content
1976
1977 - uid is a unique message identifier
1978*/
1979
1980struct mailimap_msg_att_static {
1981 int att_type;
1982 union {
1983 struct mailimap_envelope * att_env; /* can be NULL */
1984 struct mailimap_date_time * att_internal_date; /* can be NULL */
1985 struct {
1986 char * att_content; /* can be NULL */
1987 size_t att_length;
1988 } att_rfc822;
1989 struct {
1990 char * att_content; /* can be NULL */
1991 size_t att_length;
1992 } att_rfc822_header;
1993 struct {
1994 char * att_content; /* can be NULL */
1995 size_t att_length;
1996 } att_rfc822_text;
1997 uint32_t att_rfc822_size;
1998 struct mailimap_body * att_bodystructure; /* can be NULL */
1999 struct mailimap_body * att_body; /* can be NULL */
2000 struct mailimap_msg_att_body_section * att_body_section; /* can be NULL */
2001 uint32_t att_uid;
2002 } att_data;
2003};
2004
2005struct mailimap_msg_att_static *
2006mailimap_msg_att_static_new(int att_type, struct mailimap_envelope * att_env,
2007 struct mailimap_date_time * att_internal_date,
2008 char * att_rfc822,
2009 char * att_rfc822_header,
2010 char * att_rfc822_text,
2011 size_t att_length,
2012 uint32_t att_rfc822_size,
2013 struct mailimap_body * att_bodystructure,
2014 struct mailimap_body * att_body,
2015 struct mailimap_msg_att_body_section * att_body_section,
2016 uint32_t att_uid);
2017
2018void
2019mailimap_msg_att_static_free(struct mailimap_msg_att_static * item);
2020
2021
2022
2023/* this is the type of a response element */
2024
2025enum {
2026 MAILIMAP_RESP_ERROR, /* on parse error */
2027 MAILIMAP_RESP_CONT_REQ, /* continuation request */
2028 MAILIMAP_RESP_RESP_DATA, /* response data */
2029};
2030
2031/*
2032 mailimap_cont_req_or_resp_data is a response element
2033
2034 - type is the type of response, the value can be MAILIMAP_RESP_CONT_REQ
2035 or MAILIMAP_RESP_RESP_DATA
2036
2037 - cont_req is a continuation request
2038
2039 - resp_data is a reponse data
2040*/
2041
2042struct mailimap_cont_req_or_resp_data {
2043 int rsp_type;
2044 union {
2045 struct mailimap_continue_req * rsp_cont_req; /* can be NULL */
2046 struct mailimap_response_data * rsp_resp_data; /* can be NULL */
2047 } rsp_data;
2048};
2049
2050struct mailimap_cont_req_or_resp_data *
2051mailimap_cont_req_or_resp_data_new(int rsp_type,
2052 struct mailimap_continue_req * rsp_cont_req,
2053 struct mailimap_response_data * rsp_resp_data);
2054
2055void
2056mailimap_cont_req_or_resp_data_free(struct mailimap_cont_req_or_resp_data *
2057 cont_req_or_resp_data);
2058
2059
2060/*
2061 mailimap_response is a list of response elements
2062
2063 - cont_req_or_resp_data_list is a list of response elements
2064
2065 - resp_done is an ending response element
2066*/
2067
2068struct mailimap_response {
2069 clist * rsp_cont_req_or_resp_data_list;
2070 /* list of (struct mailiap_cont_req_or_resp_data *) */
2071 /* can be NULL */
2072 struct mailimap_response_done * rsp_resp_done; /* != NULL */
2073};
2074
2075struct mailimap_response *
2076mailimap_response_new(clist * rsp_cont_req_or_resp_data_list,
2077 struct mailimap_response_done * rsp_resp_done);
2078
2079void
2080mailimap_response_free(struct mailimap_response * resp);
2081
2082
2083
2084/* this is the type of an untagged response */
2085
2086enum {
2087 MAILIMAP_RESP_DATA_TYPE_ERROR, /* on parse error */
2088 MAILIMAP_RESP_DATA_TYPE_COND_STATE, /* condition state response */
2089 MAILIMAP_RESP_DATA_TYPE_COND_BYE, /* BYE response (server is about
2090 to close the connection) */
2091 MAILIMAP_RESP_DATA_TYPE_MAILBOX_DATA, /* response related to a mailbox */
2092 MAILIMAP_RESP_DATA_TYPE_MESSAGE_DATA, /* response related to a message */
2093 MAILIMAP_RESP_DATA_TYPE_CAPABILITY_DATA, /* capability information */
2094};
2095
2096/*
2097 mailimap_reponse_data is an untagged response
2098
2099 - type is the type of the untagged response, it can be
2100 MAILIMAP_RESP_DATA_COND_STATE, MAILIMAP_RESP_DATA_COND_BYE,
2101 MAILIMAP_RESP_DATA_MAILBOX_DATA, MAILIMAP_RESP_DATA_MESSAGE_DATA
2102 or MAILIMAP_RESP_DATA_CAPABILITY_DATA
2103
2104 - cond_state is a condition state response
2105
2106 - bye is a BYE response (server is about to close the connection)
2107
2108 - mailbox_data is a response related to a mailbox
2109
2110 - message_data is a response related to a message
2111
2112 - capability is information about capabilities
2113*/
2114
2115struct mailimap_response_data {
2116 int rsp_type;
2117 union {
2118 struct mailimap_resp_cond_state * rsp_cond_state; /* can be NULL */
2119 struct mailimap_resp_cond_bye * rsp_bye; /* can be NULL */
2120 struct mailimap_mailbox_data * rsp_mailbox_data; /* can be NULL */
2121 struct mailimap_message_data * rsp_message_data; /* can be NULL */
2122 struct mailimap_capability_data * rsp_capability_data; /* can be NULL */
2123 } rsp_data;
2124};
2125
2126struct mailimap_response_data *
2127mailimap_response_data_new(int rsp_type,
2128 struct mailimap_resp_cond_state * rsp_cond_state,
2129 struct mailimap_resp_cond_bye * rsp_bye,
2130 struct mailimap_mailbox_data * rsp_mailbox_data,
2131 struct mailimap_message_data * rsp_message_data,
2132 struct mailimap_capability_data * rsp_capability_data);
2133
2134void
2135mailimap_response_data_free(struct mailimap_response_data * resp_data);
2136
2137
2138
2139/* this is the type of an ending response */
2140
2141enum {
2142 MAILIMAP_RESP_DONE_TYPE_ERROR, /* on parse error */
2143 MAILIMAP_RESP_DONE_TYPE_TAGGED, /* tagged response */
2144 MAILIMAP_RESP_DONE_TYPE_FATAL, /* fatal error response */
2145};
2146
2147/*
2148 mailimap_response_done is an ending response
2149
2150 - type is the type of the ending response
2151
2152 - tagged is a tagged response
2153
2154 - fatal is a fatal error response
2155*/
2156
2157struct mailimap_response_done {
2158 int rsp_type;
2159 union {
2160 struct mailimap_response_tagged * rsp_tagged; /* can be NULL */
2161 struct mailimap_response_fatal * rsp_fatal; /* can be NULL */
2162 } rsp_data;
2163};
2164
2165struct mailimap_response_done *
2166mailimap_response_done_new(int rsp_type,
2167 struct mailimap_response_tagged * rsp_tagged,
2168 struct mailimap_response_fatal * rsp_fatal);
2169
2170void mailimap_response_done_free(struct mailimap_response_done *
2171 resp_done);
2172
2173
2174/*
2175 mailimap_response_fatal is a fatal error response
2176
2177 - bye is a BYE response text
2178*/
2179
2180struct mailimap_response_fatal {
2181 struct mailimap_resp_cond_bye * rsp_bye; /* != NULL */
2182};
2183
2184struct mailimap_response_fatal *
2185mailimap_response_fatal_new(struct mailimap_resp_cond_bye * rsp_bye);
2186
2187void mailimap_response_fatal_free(struct mailimap_response_fatal * resp_fatal);
2188
2189
2190
2191/*
2192 mailimap_response_tagged is a tagged response
2193
2194 - tag is the sent tag, should be allocated with malloc()
2195
2196 - cond_state is a condition state response
2197*/
2198
2199struct mailimap_response_tagged {
2200 char * rsp_tag; /* != NULL */
2201 struct mailimap_resp_cond_state * rsp_cond_state; /* != NULL */
2202};
2203
2204struct mailimap_response_tagged *
2205mailimap_response_tagged_new(char * rsp_tag,
2206 struct mailimap_resp_cond_state * rsp_cond_state);
2207
2208void
2209mailimap_response_tagged_free(struct mailimap_response_tagged * tagged);
2210
2211
2212/* this is the type of an authentication condition response */
2213
2214enum {
2215 MAILIMAP_RESP_COND_AUTH_ERROR, /* on parse error */
2216 MAILIMAP_RESP_COND_AUTH_OK, /* authentication is needed */
2217 MAILIMAP_RESP_COND_AUTH_PREAUTH, /* authentication is not needed */
2218};
2219
2220/*
2221 mailimap_resp_cond_auth is an authentication condition response
2222
2223 - type is the type of the authentication condition response,
2224 the value can be MAILIMAP_RESP_COND_AUTH_OK or
2225 MAILIMAP_RESP_COND_AUTH_PREAUTH
2226
2227 - text is a text response
2228*/
2229
2230struct mailimap_resp_cond_auth {
2231 int rsp_type;
2232 struct mailimap_resp_text * rsp_text; /* != NULL */
2233};
2234
2235struct mailimap_resp_cond_auth *
2236mailimap_resp_cond_auth_new(int rsp_type,
2237 struct mailimap_resp_text * rsp_text);
2238
2239void
2240mailimap_resp_cond_auth_free(struct mailimap_resp_cond_auth * cond_auth);
2241
2242
2243
2244/*
2245 mailimap_resp_cond_bye is a BYE response
2246
2247 - text is a text response
2248*/
2249
2250struct mailimap_resp_cond_bye {
2251 struct mailimap_resp_text * rsp_text; /* != NULL */
2252};
2253
2254struct mailimap_resp_cond_bye *
2255mailimap_resp_cond_bye_new(struct mailimap_resp_text * rsp_text);
2256
2257void
2258mailimap_resp_cond_bye_free(struct mailimap_resp_cond_bye * cond_bye);
2259
2260
2261
2262/* this is the type of a condition state response */
2263
2264enum {
2265 MAILIMAP_RESP_COND_STATE_OK,
2266 MAILIMAP_RESP_COND_STATE_NO,
2267 MAILIMAP_RESP_COND_STATE_BAD
2268};
2269
2270/*
2271 mailimap_resp_cond_state is a condition state reponse
2272
2273 - type is the type of the condition state response
2274
2275 - text is a text response
2276*/
2277
2278struct mailimap_resp_cond_state {
2279 int rsp_type;
2280 struct mailimap_resp_text * rsp_text; /* can be NULL */
2281};
2282
2283struct mailimap_resp_cond_state *
2284mailimap_resp_cond_state_new(int rsp_type,
2285 struct mailimap_resp_text * rsp_text);
2286
2287void
2288mailimap_resp_cond_state_free(struct mailimap_resp_cond_state * cond_state);
2289
2290
2291
2292/*
2293 mailimap_resp_text is a text response
2294
2295 - resp_code is a response code
2296
2297 - text is a human readable text, should be allocated with malloc()
2298*/
2299
2300struct mailimap_resp_text {
2301 struct mailimap_resp_text_code * rsp_code; /* can be NULL */
2302 char * rsp_text; /* can be NULL */
2303};
2304
2305struct mailimap_resp_text *
2306mailimap_resp_text_new(struct mailimap_resp_text_code * resp_code,
2307 char * rsp_text);
2308
2309void mailimap_resp_text_free(struct mailimap_resp_text * resp_text);
2310
2311
2312
2313/* this is the type of the response code */
2314
2315enum {
2316 MAILIMAP_RESP_TEXT_CODE_ALERT, /* ALERT response */
2317 MAILIMAP_RESP_TEXT_CODE_BADCHARSET, /* BADCHARSET response */
2318 MAILIMAP_RESP_TEXT_CODE_CAPABILITY_DATA, /* CAPABILITY response */
2319 MAILIMAP_RESP_TEXT_CODE_PARSE, /* PARSE response */
2320 MAILIMAP_RESP_TEXT_CODE_PERMANENTFLAGS, /* PERMANENTFLAGS response */
2321 MAILIMAP_RESP_TEXT_CODE_READ_ONLY, /* READONLY response */
2322 MAILIMAP_RESP_TEXT_CODE_READ_WRITE, /* READWRITE response */
2323 MAILIMAP_RESP_TEXT_CODE_TRY_CREATE, /* TRYCREATE response */
2324 MAILIMAP_RESP_TEXT_CODE_UIDNEXT, /* UIDNEXT response */
2325 MAILIMAP_RESP_TEXT_CODE_UIDVALIDITY, /* UIDVALIDITY response */
2326 MAILIMAP_RESP_TEXT_CODE_UNSEEN, /* UNSEEN response */
2327 MAILIMAP_RESP_TEXT_CODE_OTHER, /* other type of response */
2328};
2329
2330/*
2331 mailimap_resp_text_code is a response code
2332
2333 - type is the type of the response code, the value can be
2334 MAILIMAP_RESP_TEXT_CODE_ALERT, MAILIMAP_RESP_TEXT_CODE_BADCHARSET,
2335 MAILIMAP_RESP_TEXT_CODE_CAPABILITY_DATA, MAILIMAP_RESP_TEXT_CODE_PARSE,
2336 MAILIMAP_RESP_TEXT_CODE_PERMANENTFLAGS, MAILIMAP_RESP_TEXT_CODE_READ_ONLY,
2337 MAILIMAP_RESP_TEXT_CODE_READ_WRITE, MAILIMAP_RESP_TEXT_CODE_TRY_CREATE,
2338 MAILIMAP_RESP_TEXT_CODE_UIDNEXT, MAILIMAP_RESP_TEXT_CODE_UIDVALIDITY,
2339 MAILIMAP_RESP_TEXT_CODE_UNSEEN or MAILIMAP_RESP_TEXT_CODE_OTHER
2340
2341 - badcharset is a list of charsets if type
2342 is MAILIMAP_RESP_TEXT_CODE_BADCHARSET, each element should be
2343 allocated with malloc()
2344
2345 - cap_data is a list of capabilities
2346
2347 - perm_flags is a list of flags, this is the flags that can be changed
2348 permanently on the messages of the mailbox.
2349
2350 - uidnext is the next unique identifier of a message
2351
2352 - uidvalidity is the unique identifier validity value
2353
2354 - first_unseen is the number of the first message without the \Seen flag
2355
2356 - atom is a keyword for an extension response code, should be allocated
2357 with malloc()
2358
2359 - atom_value is the data related with the extension response code,
2360 should be allocated with malloc()
2361*/
2362
2363struct mailimap_resp_text_code {
2364 int rc_type;
2365 union {
2366 clist * rc_badcharset; /* list of astring (char *) */
2367 /* can be NULL */
2368 struct mailimap_capability_data * rc_cap_data; /* != NULL */
2369 clist * rc_perm_flags; /* list of (struct mailimap_flag_perm *) */
2370 /* can be NULL */
2371 uint32_t rc_uidnext;
2372 uint32_t rc_uidvalidity;
2373 uint32_t rc_first_unseen;
2374 struct {
2375 char * atom_name; /* can be NULL */
2376 char * atom_value; /* can be NULL */
2377 } rc_atom;
2378 } rc_data;
2379};
2380
2381struct mailimap_resp_text_code *
2382mailimap_resp_text_code_new(int rc_type, clist * rc_badcharset,
2383 struct mailimap_capability_data * rc_cap_data,
2384 clist * rc_perm_flags,
2385 uint32_t rc_uidnext, uint32_t rc_uidvalidity,
2386 uint32_t rc_first_unseen, char * rc_atom, char * rc_atom_value);
2387
2388void
2389mailimap_resp_text_code_free(struct mailimap_resp_text_code * resp_text_code);
2390
2391
2392/*
2393 mailimap_section is a MIME part section identifier
2394
2395 section_spec is the MIME section identifier
2396*/
2397
2398struct mailimap_section {
2399 struct mailimap_section_spec * sec_spec; /* can be NULL */
2400};
2401
2402struct mailimap_section *
2403mailimap_section_new(struct mailimap_section_spec * sec_spec);
2404
2405void mailimap_section_free(struct mailimap_section * section);
2406
2407
2408/* this is the type of the message/rfc822 part description */
2409
2410enum {
2411 MAILIMAP_SECTION_MSGTEXT_HEADER, /* header fields part of the
2412 message */
2413 MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS, /* given header fields of the
2414 message */
2415 MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT, /* header fields of the
2416 message except the given */
2417 MAILIMAP_SECTION_MSGTEXT_TEXT, /* text part */
2418};
2419
2420/*
2421 mailimap_section_msgtext is a message/rfc822 part description
2422
2423 - type is the type of the content part and the value can be
2424 MAILIMAP_SECTION_MSGTEXT_HEADER, MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS,
2425 MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT
2426 or MAILIMAP_SECTION_MSGTEXT_TEXT
2427
2428 - header_list is the list of headers when type is
2429 MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS or
2430 MAILIMAP_SECTION_MSGTEXT_HEADER_FIELDS_NOT
2431*/
2432
2433struct mailimap_section_msgtext {
2434 int sec_type;
2435 struct mailimap_header_list * sec_header_list; /* can be NULL */
2436};
2437
2438struct mailimap_section_msgtext *
2439mailimap_section_msgtext_new(int sec_type,
2440 struct mailimap_header_list * sec_header_list);
2441
2442void
2443mailimap_section_msgtext_free(struct mailimap_section_msgtext * msgtext);
2444
2445
2446
2447/*
2448 mailimap_section_part is the MIME part location in a message
2449
2450 - section_id is a list of number index of the sub-part in the mail structure,
2451 each element should be allocated with malloc()
2452
2453*/
2454
2455struct mailimap_section_part {
2456 clist * sec_id; /* list of nz-number (uint32_t *) */
2457 /* != NULL */
2458};
2459
2460struct mailimap_section_part *
2461mailimap_section_part_new(clist * sec_id);
2462
2463void
2464mailimap_section_part_free(struct mailimap_section_part * section_part);
2465
2466
2467
2468/* this is the type of section specification */
2469
2470enum {
2471 MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT, /* if requesting data of the root
2472 MIME message/rfc822 part */
2473 MAILIMAP_SECTION_SPEC_SECTION_PART, /* location of the MIME part
2474 in the message */
2475};
2476
2477/*
2478 mailimap_section_spec is a section specification
2479
2480 - type is the type of the section specification, the value can be
2481 MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT or
2482 MAILIMAP_SECTION_SPEC_SECTION_PART
2483
2484 - section_msgtext is a message/rfc822 part description if type is
2485 MAILIMAP_SECTION_SPEC_SECTION_MSGTEXT
2486
2487 - section_part is a body part location in the message if type is
2488 MAILIMAP_SECTION_SPEC_SECTION_PART
2489
2490 - section_text is a body part location for a given MIME part,
2491 this can be NULL if the body of the part is requested (and not
2492 the MIME header).
2493*/
2494
2495struct mailimap_section_spec {
2496 int sec_type;
2497 union {
2498 struct mailimap_section_msgtext * sec_msgtext; /* can be NULL */
2499 struct mailimap_section_part * sec_part; /* can be NULL */
2500 } sec_data;
2501 struct mailimap_section_text * sec_text; /* can be NULL */
2502};
2503
2504struct mailimap_section_spec *
2505mailimap_section_spec_new(int sec_type,
2506 struct mailimap_section_msgtext * sec_msgtext,
2507 struct mailimap_section_part * sec_part,
2508 struct mailimap_section_text * sec_text);
2509
2510void
2511mailimap_section_spec_free(struct mailimap_section_spec * section_spec);
2512
2513
2514
2515/* this is the type of body part location for a given MIME part */
2516
2517enum {
2518 MAILIMAP_SECTION_TEXT_ERROR, /* on parse error **/
2519 MAILIMAP_SECTION_TEXT_SECTION_MSGTEXT, /* if the MIME type is
2520 message/rfc822, headers or text
2521 can be requested */
2522 MAILIMAP_SECTION_TEXT_MIME, /* for all MIME types,
2523 MIME headers can be requested */
2524};
2525
2526/*
2527 mailimap_section_text is the body part location for a given MIME part
2528
2529 - type can be MAILIMAP_SECTION_TEXT_SECTION_MSGTEXT or
2530 MAILIMAP_SECTION_TEXT_MIME
2531
2532 - section_msgtext is the part of the MIME part when MIME type is
2533 message/rfc822 than can be requested, when type is
2534 MAILIMAP_TEXT_SECTION_MSGTEXT
2535*/
2536
2537struct mailimap_section_text {
2538 int sec_type;
2539 struct mailimap_section_msgtext * sec_msgtext; /* can be NULL */
2540};
2541
2542struct mailimap_section_text *
2543mailimap_section_text_new(int sec_type,
2544 struct mailimap_section_msgtext * sec_msgtext);
2545
2546void
2547mailimap_section_text_free(struct mailimap_section_text * section_text);
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558/* ************************************************************************* */
2559/* the following part concerns only the IMAP command that are sent */
2560
2561
2562/*
2563 mailimap_set_item is a message set
2564
2565 - first is the first message of the set
2566 - last is the last message of the set
2567
2568 this can be message numbers of message unique identifiers
2569*/
2570
2571struct mailimap_set_item {
2572 uint32_t set_first;
2573 uint32_t set_last;
2574};
2575
2576struct mailimap_set_item *
2577mailimap_set_item_new(uint32_t set_first, uint32_t set_last);
2578
2579void mailimap_set_item_free(struct mailimap_set_item * set_item);
2580
2581
2582
2583/*
2584 set is a list of message sets
2585
2586 - list is a list of message sets
2587*/
2588
2589struct mailimap_set {
2590 clist * set_list; /* list of (struct mailimap_set_item *) */
2591};
2592
2593struct mailimap_set * mailimap_set_new(clist * list);
2594
2595void mailimap_set_free(struct mailimap_set * set);
2596
2597
2598/*
2599 mailimap_date is a date
2600
2601 - day is the day in the month (1 to 31)
2602
2603 - month (1 to 12)
2604
2605 - year (4 digits)
2606*/
2607
2608struct mailimap_date {
2609 int dt_day;
2610 int dt_month;
2611 int dt_year;
2612};
2613
2614struct mailimap_date *
2615mailimap_date_new(int dt_day, int dt_month, int dt_year);
2616
2617void mailimap_date_free(struct mailimap_date * date);
2618
2619
2620
2621
2622/* this is the type of fetch attribute for a given message */
2623
2624enum {
2625 MAILIMAP_FETCH_ATT_ENVELOPE, /* to fetch the headers parsed by
2626 the IMAP server */
2627 MAILIMAP_FETCH_ATT_FLAGS, /* to fetch the flags */
2628 MAILIMAP_FETCH_ATT_INTERNALDATE, /* to fetch the date of the message
2629 kept by the server */
2630 MAILIMAP_FETCH_ATT_RFC822, /* to fetch the entire message */
2631 MAILIMAP_FETCH_ATT_RFC822_HEADER, /* to fetch the headers */
2632 MAILIMAP_FETCH_ATT_RFC822_SIZE, /* to fetch the size */
2633 MAILIMAP_FETCH_ATT_RFC822_TEXT, /* to fetch the text part */
2634 MAILIMAP_FETCH_ATT_BODY, /* to fetch the MIME structure */
2635 MAILIMAP_FETCH_ATT_BODYSTRUCTURE, /* to fetch the MIME structure with
2636 additional information */
2637 MAILIMAP_FETCH_ATT_UID, /* to fetch the unique identifier */
2638 MAILIMAP_FETCH_ATT_BODY_SECTION, /* to fetch a given part */
2639 MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION, /* to fetch a given part without
2640 marking the message as read */
2641};
2642
2643
2644/*
2645 mailimap_fetch_att is the description of the fetch attribute
2646
2647 - type is the type of fetch attribute, the value can be
2648 MAILIMAP_FETCH_ATT_ENVELOPE, MAILIMAP_FETCH_ATT_FLAGS,
2649 MAILIMAP_FETCH_ATT_INTERNALDATE, MAILIMAP_FETCH_ATT_RFC822,
2650 MAILIMAP_FETCH_ATT_RFC822_HEADER, MAILIMAP_FETCH_ATT_RFC822_SIZE,
2651 MAILIMAP_FETCH_ATT_RFC822_TEXT, MAILIMAP_FETCH_ATT_BODY,
2652 MAILIMAP_FETCH_ATT_BODYSTRUCTURE, MAILIMAP_FETCH_ATT_UID,
2653 MAILIMAP_FETCH_ATT_BODY_SECTION or MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION
2654
2655 - section is the location of the part to fetch if type is
2656 MAILIMAP_FETCH_ATT_BODY_SECTION or MAILIMAP_FETCH_ATT_BODY_PEEK_SECTION
2657
2658 - offset is the first byte to fetch in the given part
2659
2660 - size is the maximum size of the part to fetch
2661*/
2662
2663struct mailimap_fetch_att {
2664 int att_type;
2665 struct mailimap_section * att_section;
2666 uint32_t att_offset;
2667 uint32_t att_size;
2668};
2669
2670struct mailimap_fetch_att *
2671mailimap_fetch_att_new(int att_type, struct mailimap_section * att_section,
2672 uint32_t att_offset, uint32_t att_size);
2673
2674
2675void mailimap_fetch_att_free(struct mailimap_fetch_att * fetch_att);
2676
2677
2678/* this is the type of a FETCH operation */
2679
2680enum {
2681 MAILIMAP_FETCH_TYPE_ALL, /* equivalent to (FLAGS INTERNALDATE
2682 RFC822.SIZE ENVELOPE) */
2683 MAILIMAP_FETCH_TYPE_FULL, /* equivalent to (FLAGS INTERNALDATE
2684 RFC822.SIZE ENVELOPE BODY) */
2685 MAILIMAP_FETCH_TYPE_FAST, /* equivalent to (FLAGS INTERNALDATE
2686 RFC822.SIZE) */
2687 MAILIMAP_FETCH_TYPE_FETCH_ATT, /* when there is only of fetch
2688 attribute */
2689 MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST, /* when there is a list of fetch
2690 attributes */
2691};
2692
2693/*
2694 mailimap_fetch_type is the description of the FETCH operation
2695
2696 - type can be MAILIMAP_FETCH_TYPE_ALL, MAILIMAP_FETCH_TYPE_FULL,
2697 MAILIMAP_FETCH_TYPE_FAST, MAILIMAP_FETCH_TYPE_FETCH_ATT or
2698 MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST
2699
2700 - fetch_att is a fetch attribute if type is MAILIMAP_FETCH_TYPE_FETCH_ATT
2701
2702 - fetch_att_list is a list of fetch attributes if type is
2703 MAILIMAP_FETCH_TYPE_FETCH_ATT_LIST
2704*/
2705
2706struct mailimap_fetch_type {
2707 int ft_type;
2708 union {
2709 struct mailimap_fetch_att * ft_fetch_att;
2710 clist * ft_fetch_att_list; /* list of (struct mailimap_fetch_att *) */
2711 } ft_data;
2712};
2713
2714struct mailimap_fetch_type *
2715mailimap_fetch_type_new(int ft_type,
2716 struct mailimap_fetch_att * ft_fetch_att,
2717 clist * ft_fetch_att_list);
2718
2719
2720void mailimap_fetch_type_free(struct mailimap_fetch_type * fetch_type);
2721
2722
2723
2724/*
2725 mailimap_store_att_flags is the description of the STORE operation
2726 (change flags of a message)
2727
2728 - sign can be 0 (set flag), +1 (add flag) or -1 (remove flag)
2729
2730 - silent has a value of 1 if the flags are changed with no server
2731 response
2732
2733 - flag_list is the list of flags to change
2734*/
2735
2736struct mailimap_store_att_flags {
2737 int fl_sign;
2738 int fl_silent;
2739 struct mailimap_flag_list * fl_flag_list;
2740};
2741
2742struct mailimap_store_att_flags *
2743mailimap_store_att_flags_new(int fl_sign, int fl_silent,
2744 struct mailimap_flag_list * fl_flag_list);
2745
2746void mailimap_store_att_flags_free(struct mailimap_store_att_flags *
2747 store_att_flags);
2748
2749
2750
2751/* this is the condition of the SEARCH operation */
2752
2753enum {
2754 MAILIMAP_SEARCH_KEY_ALL, /* all messages */
2755 MAILIMAP_SEARCH_KEY_ANSWERED, /* messages with the flag \Answered */
2756 MAILIMAP_SEARCH_KEY_BCC, /* messages whose Bcc field contains the
2757 given string */
2758 MAILIMAP_SEARCH_KEY_BEFORE, /* messages whose internal date is earlier
2759 than the specified date */
2760 MAILIMAP_SEARCH_KEY_BODY, /* message that contains the given string
2761 (in header and text parts) */
2762 MAILIMAP_SEARCH_KEY_CC, /* messages whose Cc field contains the
2763 given string */
2764 MAILIMAP_SEARCH_KEY_DELETED, /* messages with the flag \Deleted */
2765 MAILIMAP_SEARCH_KEY_FLAGGED, /* messages with the flag \Flagged */
2766 MAILIMAP_SEARCH_KEY_FROM, /* messages whose From field contains the
2767 given string */
2768 MAILIMAP_SEARCH_KEY_KEYWORD, /* messages with the flag keyword set */
2769 MAILIMAP_SEARCH_KEY_NEW, /* messages with the flag \Recent and not
2770 the \Seen flag */
2771 MAILIMAP_SEARCH_KEY_OLD, /* messages that do not have the
2772 \Recent flag set */
2773 MAILIMAP_SEARCH_KEY_ON, /* messages whose internal date is the
2774 specified date */
2775 MAILIMAP_SEARCH_KEY_RECENT, /* messages with the flag \Recent */
2776 MAILIMAP_SEARCH_KEY_SEEN, /* messages with the flag \Seen */
2777 MAILIMAP_SEARCH_KEY_SINCE, /* messages whose internal date is later
2778 than specified date */
2779 MAILIMAP_SEARCH_KEY_SUBJECT, /* messages whose Subject field contains the
2780 given string */
2781 MAILIMAP_SEARCH_KEY_TEXT, /* messages whose text part contains the
2782 given string */
2783 MAILIMAP_SEARCH_KEY_TO, /* messages whose To field contains the
2784 given string */
2785 MAILIMAP_SEARCH_KEY_UNANSWERED, /* messages with no flag \Answered */
2786 MAILIMAP_SEARCH_KEY_UNDELETED, /* messages with no flag \Deleted */
2787 MAILIMAP_SEARCH_KEY_UNFLAGGED, /* messages with no flag \Flagged */
2788 MAILIMAP_SEARCH_KEY_UNKEYWORD, /* messages with no flag keyword */
2789 MAILIMAP_SEARCH_KEY_UNSEEN, /* messages with no flag \Seen */
2790 MAILIMAP_SEARCH_KEY_DRAFT, /* messages with no flag \Draft */
2791 MAILIMAP_SEARCH_KEY_HEADER, /* messages whose given field
2792 contains the given string */
2793 MAILIMAP_SEARCH_KEY_LARGER, /* messages whose size is larger then
2794 the given size */
2795 MAILIMAP_SEARCH_KEY_NOT, /* not operation of the condition */
2796 MAILIMAP_SEARCH_KEY_OR, /* or operation between two conditions */
2797 MAILIMAP_SEARCH_KEY_SENTBEFORE, /* messages whose date given in Date header
2798 is earlier than the specified date */
2799 MAILIMAP_SEARCH_KEY_SENTON, /* messages whose date given in Date header
2800 is the specified date */
2801 MAILIMAP_SEARCH_KEY_SENTSINCE, /* messages whose date given in Date header
2802 is later than specified date */
2803 MAILIMAP_SEARCH_KEY_SMALLER, /* messages whose size is smaller than
2804 the given size */
2805 MAILIMAP_SEARCH_KEY_UID, /* messages whose unique identifiers are
2806 in the given range */
2807 MAILIMAP_SEARCH_KEY_UNDRAFT, /* messages with no flag \Draft */
2808 MAILIMAP_SEARCH_KEY_SET, /* messages whose number (or unique
2809 identifiers in case of UID SEARCH) are
2810 in the given range */
2811 MAILIMAP_SEARCH_KEY_MULTIPLE, /* the boolean operator between the
2812 conditions is AND */
2813};
2814
2815/*
2816 mailimap_search_key is the condition on the messages to return
2817
2818 - type is the type of the condition
2819
2820 - bcc is the text to search in the Bcc field when type is
2821 MAILIMAP_SEARCH_KEY_BCC, should be allocated with malloc()
2822
2823 - before is a date when type is MAILIMAP_SEARCH_KEY_BEFORE
2824
2825 - body is the text to search in the message when type is
2826 MAILIMAP_SEARCH_KEY_BODY, should be allocated with malloc()
2827
2828 - cc is the text to search in the Cc field when type is
2829 MAILIMAP_SEARCH_KEY_CC, should be allocated with malloc()
2830
2831 - from is the text to search in the From field when type is
2832 MAILIMAP_SEARCH_KEY_FROM, should be allocated with malloc()
2833
2834 - keyword is the keyword flag name when type is MAILIMAP_SEARCH_KEY_KEYWORD,
2835 should be allocated with malloc()
2836
2837 - on is a date when type is MAILIMAP_SEARCH_KEY_ON
2838
2839 - since is a date when type is MAILIMAP_SEARCH_KEY_SINCE
2840
2841 - subject is the text to search in the Subject field when type is
2842 MAILIMAP_SEARCH_KEY_SUBJECT, should be allocated with malloc()
2843
2844 - text is the text to search in the text part of the message when
2845 type is MAILIMAP_SEARCH_KEY_TEXT, should be allocated with malloc()
2846
2847 - to is the text to search in the To field when type is
2848 MAILIMAP_SEARCH_KEY_TO, should be allocated with malloc()
2849
2850 - unkeyword is the keyword flag name when type is
2851 MAILIMAP_SEARCH_KEY_UNKEYWORD, should be allocated with malloc()
2852
2853 - header_name is the header name when type is MAILIMAP_SEARCH_KEY_HEADER,
2854 should be allocated with malloc()
2855
2856 - header_value is the text to search in the given header when type is
2857 MAILIMAP_SEARCH_KEY_HEADER, should be allocated with malloc()
2858
2859 - larger is a size when type is MAILIMAP_SEARCH_KEY_LARGER
2860
2861 - not is a condition when type is MAILIMAP_SEARCH_KEY_NOT
2862
2863 - or1 is a condition when type is MAILIMAP_SEARCH_KEY_OR
2864
2865 - or2 is a condition when type is MAILIMAP_SEARCH_KEY_OR
2866
2867 - sentbefore is a date when type is MAILIMAP_SEARCH_KEY_SENTBEFORE
2868
2869 - senton is a date when type is MAILIMAP_SEARCH_KEY_SENTON
2870
2871 - sentsince is a date when type is MAILIMAP_SEARCH_KEY_SENTSINCE
2872
2873 - smaller is a size when type is MAILIMAP_SEARCH_KEY_SMALLER
2874
2875 - uid is a set of messages when type is MAILIMAP_SEARCH_KEY_UID
2876
2877 - set is a set of messages when type is MAILIMAP_SEARCH_KEY_SET
2878
2879 - multiple is a set of message when type is MAILIMAP_SEARCH_KEY_MULTIPLE
2880*/
2881
2882struct mailimap_search_key {
2883 int sk_type;
2884 union {
2885 char * sk_bcc;
2886 struct mailimap_date * sk_before;
2887 char * sk_body;
2888 char * sk_cc;
2889 char * sk_from;
2890 char * sk_keyword;
2891 struct mailimap_date * sk_on;
2892 struct mailimap_date * sk_since;
2893 char * sk_subject;
2894 char * sk_text;
2895 char * sk_to;
2896 char * sk_unkeyword;
2897 struct {
2898 char * sk_header_name;
2899 char * sk_header_value;
2900 } sk_header;
2901 uint32_t sk_larger;
2902 struct mailimap_search_key * sk_not;
2903 struct {
2904 struct mailimap_search_key * sk_or1;
2905 struct mailimap_search_key * sk_or2;
2906 } sk_or;
2907 struct mailimap_date * sk_sentbefore;
2908 struct mailimap_date * sk_senton;
2909 struct mailimap_date * sk_sentsince;
2910 uint32_t sk_smaller;
2911 struct mailimap_set * sk_uid;
2912 struct mailimap_set * sk_set;
2913 clist * sk_multiple; /* list of (struct mailimap_search_key *) */
2914 } sk_data;
2915};
2916
2917struct mailimap_search_key *
2918mailimap_search_key_new(int sk_type,
2919 char * sk_bcc, struct mailimap_date * sk_before, char * sk_body,
2920 char * sk_cc, char * sk_from, char * sk_keyword,
2921 struct mailimap_date * sk_on, struct mailimap_date * sk_since,
2922 char * sk_subject, char * sk_text, char * sk_to,
2923 char * sk_unkeyword, char * sk_header_name,
2924 char * sk_header_value, uint32_t sk_larger,
2925 struct mailimap_search_key * sk_not,
2926 struct mailimap_search_key * sk_or1,
2927 struct mailimap_search_key * sk_or2,
2928 struct mailimap_date * sk_sentbefore,
2929 struct mailimap_date * sk_senton,
2930 struct mailimap_date * sk_sentsince,
2931 uint32_t sk_smaller, struct mailimap_set * sk_uid,
2932 struct mailimap_set * sk_set, clist * sk_multiple);
2933
2934
2935void mailimap_search_key_free(struct mailimap_search_key * key);
2936
2937
2938/*
2939 mailimap_status_att_list is a list of mailbox STATUS request type
2940
2941 - list is a list of mailbox STATUS request type
2942 (value of elements in the list can be MAILIMAP_STATUS_ATT_MESSAGES,
2943 MAILIMAP_STATUS_ATT_RECENT, MAILIMAP_STATUS_ATT_UIDNEXT,
2944 MAILIMAP_STATUS_ATT_UIDVALIDITY or MAILIMAP_STATUS_ATT_UNSEEN),
2945 each element should be allocated with malloc()
2946*/
2947
2948struct mailimap_status_att_list {
2949 clist * att_list; /* list of (uint32_t *) */
2950};
2951
2952struct mailimap_status_att_list *
2953mailimap_status_att_list_new(clist * att_list);
2954
2955void mailimap_status_att_list_free(struct mailimap_status_att_list *
2956 status_att_list);
2957
2958
2959
2960
2961/* internal use functions */
2962
2963
2964uint32_t * mailimap_number_alloc_new(uint32_t number);
2965
2966void mailimap_number_alloc_free(uint32_t * pnumber);
2967
2968
2969void mailimap_addr_host_free(char * addr_host);
2970
2971void mailimap_addr_mailbox_free(char * addr_mailbox);
2972
2973void mailimap_addr_adl_free(char * addr_adl);
2974
2975void mailimap_addr_name_free(char * addr_name);
2976
2977void mailimap_astring_free(char * astring);
2978
2979void mailimap_atom_free(char * atom);
2980
2981void mailimap_auth_type_free(char * auth_type);
2982
2983void mailimap_base64_free(char * base64);
2984
2985void mailimap_body_fld_desc_free(char * body_fld_desc);
2986
2987void mailimap_body_fld_id_free(char * body_fld_id);
2988
2989void mailimap_body_fld_md5_free(char * body_fld_md5);
2990
2991void mailimap_env_date_free(char * date);
2992
2993void mailimap_env_in_reply_to_free(char * in_reply_to);
2994
2995void mailimap_env_message_id_free(char * message_id);
2996
2997void mailimap_env_subject_free(char * subject);
2998
2999void mailimap_flag_extension_free(char * flag_extension);
3000
3001void mailimap_flag_keyword_free(char * flag_keyword);
3002
3003void
3004mailimap_header_fld_name_free(char * header_fld_name);
3005
3006void mailimap_literal_free(char * literal);
3007
3008void mailimap_mailbox_free(char * mailbox);
3009
3010void
3011mailimap_mailbox_data_search_free(clist * data_search);
3012
3013void mailimap_media_subtype_free(char * media_subtype);
3014
3015void mailimap_media_text_free(char * media_text);
3016
3017void mailimap_msg_att_envelope_free(struct mailimap_envelope * env);
3018
3019void
3020mailimap_msg_att_internaldate_free(struct mailimap_date_time * date_time);
3021
3022void
3023mailimap_msg_att_rfc822_free(char * str);
3024
3025void
3026mailimap_msg_att_rfc822_header_free(char * str);
3027
3028void
3029mailimap_msg_att_rfc822_text_free(char * str);
3030
3031void
3032mailimap_msg_att_body_free(struct mailimap_body * body);
3033
3034void
3035mailimap_msg_att_bodystructure_free(struct mailimap_body * body);
3036
3037void mailimap_nstring_free(char * str);
3038
3039void
3040mailimap_string_free(char * str);
3041
3042void mailimap_tag_free(char * tag);
3043
3044void mailimap_text_free(char * text);
3045
3046
3047
3048
3049
3050/* IMAP connection */
3051
3052/* this is the state of the IMAP connection */
3053
3054enum {
3055 MAILIMAP_STATE_DISCONNECTED,
3056 MAILIMAP_STATE_NON_AUTHENTICATED,
3057 MAILIMAP_STATE_AUTHENTICATED,
3058 MAILIMAP_STATE_SELECTED,
3059 MAILIMAP_STATE_LOGOUT
3060};
3061
3062/*
3063 mailimap is an IMAP connection
3064
3065 - response is a human readable message returned with a reponse,
3066 must be accessed read-only
3067
3068 - stream is the connection with the IMAP server
3069
3070 - stream_buffer is the buffer where the data to parse are stored
3071
3072 - state is the state of IMAP connection
3073
3074 - tag is the current tag being used in IMAP connection
3075
3076 - response_buffer is the buffer for response messages
3077
3078 - connection_info is the information returned in response
3079 for the last command about the connection
3080
3081 - selection_info is the information returned in response
3082 for the last command about the current selected mailbox
3083
3084 - response_info is the other information returned in response
3085 for the last command
3086*/
3087
3088struct mailimap {
3089 char * imap_response;
3090
3091 /* internals */
3092 mailstream * imap_stream;
3093
3094 size_t imap_progr_rate;
3095 progress_function * imap_progr_fun;
3096
3097 MMAPString * imap_stream_buffer;
3098 MMAPString * imap_response_buffer;
3099
3100 int imap_state;
3101 int imap_tag;
3102
3103 struct mailimap_connection_info * imap_connection_info;
3104 struct mailimap_selection_info * imap_selection_info;
3105 struct mailimap_response_info * imap_response_info;
3106};
3107
3108typedef struct mailimap mailimap;
3109
3110
3111/*
3112 mailimap_connection_info is the information about the connection
3113
3114 - capability is the list of capability of the IMAP server
3115*/
3116
3117struct mailimap_connection_info {
3118 struct mailimap_capability_data * imap_capability;
3119};
3120
3121struct mailimap_connection_info *
3122mailimap_connection_info_new(void);
3123
3124void
3125mailimap_connection_info_free(struct mailimap_connection_info * conn_info);
3126
3127
3128/* this is the type of mailbox access */
3129
3130enum {
3131 MAILIMAP_MAILBOX_READONLY,
3132 MAILIMAP_MAILBOX_READWRITE
3133};
3134
3135/*
3136 mailimap_selection_info is information about the current selected mailbox
3137
3138 - perm_flags is a list of flags that can be changed permanently on the
3139 messages of the mailbox
3140
3141 - perm is the access on the mailbox, value can be
3142 MAILIMAP_MAILBOX_READONLY or MAILIMAP_MAILBOX_READWRITE
3143
3144 - uidnext is the next unique identifier
3145
3146 - uidvalidity is the unique identifiers validity
3147
3148 - first_unseen is the number of the first unseen message
3149
3150 - flags is a list of flags that can be used on the messages of
3151 the mailbox
3152
3153 - exists is the number of messages in the mailbox
3154
3155 - recent is the number of recent messages in the mailbox
3156
3157 - unseen is the number of unseen messages in the mailbox
3158*/
3159
3160struct mailimap_selection_info {
3161 clist * sel_perm_flags; /* list of (struct flag_perm *) */
3162 int sel_perm;
3163 uint32_t sel_uidnext;
3164 uint32_t sel_uidvalidity;
3165 uint32_t sel_first_unseen;
3166 struct mailimap_flag_list * sel_flags;
3167 uint32_t sel_exists;
3168 uint32_t sel_recent;
3169 uint32_t sel_unseen;
3170};
3171
3172struct mailimap_selection_info *
3173mailimap_selection_info_new(void);
3174
3175void
3176mailimap_selection_info_free(struct mailimap_selection_info * sel_info);
3177
3178
3179/*
3180 mailimap_response_info is the other information returned in the
3181 response for a command
3182
3183 - alert is the human readable text returned with ALERT response
3184
3185 - parse is the human readable text returned with PARSE response
3186
3187 - badcharset is a list of charset returned with a BADCHARSET response
3188
3189 - trycreate is set to 1 if a trycreate response was returned
3190
3191 - mailbox_list is a list of mailboxes
3192
3193 - mailbox_lsub is a list of subscribed mailboxes
3194
3195 - search_result is a list of message numbers or unique identifiers
3196
3197 - status is a STATUS response
3198
3199 - expunged is a list of message numbers
3200
3201 - fetch_list is a list of fetch response
3202*/
3203
3204struct mailimap_response_info {
3205 char * rsp_alert;
3206 char * rsp_parse;
3207 clist * rsp_badcharset; /* list of (char *) */
3208 int rsp_trycreate;
3209 clist * rsp_mailbox_list; /* list of (struct mailimap_mailbox_list *) */
3210 clist * rsp_mailbox_lsub; /* list of (struct mailimap_mailbox_list *) */
3211 clist * rsp_search_result; /* list of (uint32_t *) */
3212 struct mailimap_mailbox_data_status * rsp_status;
3213 clist * rsp_expunged; /* list of (uint32_t 32 *) */
3214 clist * rsp_fetch_list; /* list of (struct mailimap_msg_att *) */
3215};
3216
3217struct mailimap_response_info *
3218mailimap_response_info_new(void);
3219
3220void
3221mailimap_response_info_free(struct mailimap_response_info * resp_info);
3222
3223
3224/* these are the possible returned error codes */
3225
3226enum {
3227 MAILIMAP_NO_ERROR = 0,
3228 MAILIMAP_NO_ERROR_AUTHENTICATED = 1,
3229 MAILIMAP_NO_ERROR_NON_AUTHENTICATED = 2,
3230 MAILIMAP_ERROR_BAD_STATE,
3231 MAILIMAP_ERROR_STREAM,
3232 MAILIMAP_ERROR_PARSE,
3233 MAILIMAP_ERROR_CONNECTION_REFUSED,
3234 MAILIMAP_ERROR_MEMORY,
3235 MAILIMAP_ERROR_FATAL,
3236 MAILIMAP_ERROR_PROTOCOL,
3237 MAILIMAP_ERROR_DONT_ACCEPT_CONNECTION,
3238 MAILIMAP_ERROR_APPEND,
3239 MAILIMAP_ERROR_NOOP,
3240 MAILIMAP_ERROR_LOGOUT,
3241 MAILIMAP_ERROR_CAPABILITY,
3242 MAILIMAP_ERROR_CHECK,
3243 MAILIMAP_ERROR_CLOSE,
3244 MAILIMAP_ERROR_EXPUNGE,
3245 MAILIMAP_ERROR_COPY,
3246 MAILIMAP_ERROR_UID_COPY,
3247 MAILIMAP_ERROR_CREATE,
3248 MAILIMAP_ERROR_DELETE,
3249 MAILIMAP_ERROR_EXAMINE,
3250 MAILIMAP_ERROR_FETCH,
3251 MAILIMAP_ERROR_UID_FETCH,
3252 MAILIMAP_ERROR_LIST,
3253 MAILIMAP_ERROR_LOGIN,
3254 MAILIMAP_ERROR_LSUB,
3255 MAILIMAP_ERROR_RENAME,
3256 MAILIMAP_ERROR_SEARCH,
3257 MAILIMAP_ERROR_UID_SEARCH,
3258 MAILIMAP_ERROR_SELECT,
3259 MAILIMAP_ERROR_STATUS,
3260 MAILIMAP_ERROR_STORE,
3261 MAILIMAP_ERROR_UID_STORE,
3262 MAILIMAP_ERROR_SUBSCRIBE,
3263 MAILIMAP_ERROR_UNSUBSCRIBE,
3264 MAILIMAP_ERROR_STARTTLS,
3265 MAILIMAP_ERROR_INVAL,
3266};
3267
3268
3269#ifdef __cplusplus
3270}
3271#endif
3272
3273#endif
3274
diff --git a/kmicromail/libetpan/include/libetpan/mailimap_types_helper.h b/kmicromail/libetpan/include/libetpan/mailimap_types_helper.h
new file mode 100644
index 0000000..bb0bb99
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailimap_types_helper.h
@@ -0,0 +1,758 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMAP_TYPES_HELPER_H
37
38#define MAILIMAP_TYPES_HELPER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailimap_types.h>
45
46/*
47 IMPORTANT NOTE:
48
49 All allocation functions will take as argument allocated data
50 and will store these data in the structure they will allocate.
51 Data should be persistant during all the use of the structure
52 and will be freed by the free function of the structure
53
54 allocation functions will return NULL on failure
55*/
56
57/*
58 this function creates a new set item with a single message
59 given by index
60*/
61
62struct mailimap_set_item * mailimap_set_item_new_single(uint32_t index);
63
64/*
65 this function creates a new set with one set item
66 */
67
68struct mailimap_set *
69mailimap_set_new_single_item(struct mailimap_set_item * item);
70
71/*
72 this function creates a set with a single interval
73*/
74
75struct mailimap_set * mailimap_set_new_interval(uint32_t first, uint32_t last);
76
77/*
78 this function creates a set with a single message
79*/
80
81struct mailimap_set * mailimap_set_new_single(uint32_t index);
82
83/*
84 this function creates an empty set of messages
85*/
86
87struct mailimap_set * mailimap_set_new_empty(void);
88
89/*
90 this function adds a set item to the set of messages
91
92 @return MAILIMAP_NO_ERROR will be returned on success,
93 other code will be returned otherwise
94*/
95
96int mailimap_set_add(struct mailimap_set * set,
97 struct mailimap_set_item * set_item);
98
99/*
100 this function adds an interval to the set
101
102 @return MAILIMAP_NO_ERROR will be returned on success,
103 other code will be returned otherwise
104*/
105
106int mailimap_set_add_interval(struct mailimap_set * set,
107 uint32_t first, uint32_t last);
108
109/*
110 this function adds a single message to the set
111
112 @return MAILIMAP_NO_ERROR will be returned on success,
113 other code will be returned otherwise
114*/
115
116int mailimap_set_add_single(struct mailimap_set * set,
117 uint32_t index);
118
119/*
120 this function creates a mailimap_section structure to request
121 the header of a message
122*/
123
124struct mailimap_section * mailimap_section_new_header(void);
125
126/*
127 this functions creates a mailimap_section structure to describe
128 a list of headers
129*/
130
131struct mailimap_section *
132mailimap_section_new_header_fields(struct mailimap_header_list * header_list);
133
134/*
135 this functions creates a mailimap_section structure to describe headers
136 other than those given
137*/
138
139struct mailimap_section *
140mailimap_section_new_header_fields_not(struct mailimap_header_list * header_list);
141
142/*
143 this function creates a mailimap_section structure to describe the
144 text of a message
145 */
146
147struct mailimap_section * mailimap_section_new_text(void);
148
149/*
150 this function creates a mailimap_section structure to describe the
151 content of a MIME part
152*/
153
154struct mailimap_section *
155mailimap_section_new_part(struct mailimap_section_part * part);
156
157/*
158 this function creates a mailimap_section structure to describe the
159 MIME fields of a MIME part
160*/
161
162struct mailimap_section *
163mailimap_section_new_part_mime(struct mailimap_section_part * part);
164
165/*
166 this function creates a mailimap_section structure to describe the
167 headers of a MIME part if the MIME type is a message/rfc822
168*/
169
170struct mailimap_section *
171mailimap_section_new_part_header(struct mailimap_section_part * part);
172
173/*
174 this function creates a mailimap_section structure to describe
175 a list of headers of a MIME part if the MIME type is a message/rfc822
176*/
177
178struct mailimap_section *
179mailimap_section_new_part_header_fields(struct mailimap_section_part *
180 part,
181 struct mailimap_header_list *
182 header_list);
183
184/*
185 this function creates a mailimap_section structure to describe
186 headers of a MIME part other than those given if the MIME type
187 is a message/rfc822
188*/
189
190struct mailimap_section *
191mailimap_section_new_part_header_fields_not(struct mailimap_section_part
192 * part,
193 struct mailimap_header_list
194 * header_list);
195
196/*
197 this function creates a mailimap_section structure to describe
198 text part of message if the MIME type is a message/rfc822
199*/
200
201struct mailimap_section *
202mailimap_section_new_part_text(struct mailimap_section_part * part);
203
204
205/*
206 this function creates a mailimap_fetch_att structure to request
207 envelope of a message
208*/
209
210struct mailimap_fetch_att *
211mailimap_fetch_att_new_envelope(void);
212
213
214/*
215 this function creates a mailimap_fetch_att structure to request
216 flags of a message
217*/
218
219struct mailimap_fetch_att *
220mailimap_fetch_att_new_flags(void);
221
222/*
223 this function creates a mailimap_fetch_att structure to request
224 internal date of a message
225*/
226
227struct mailimap_fetch_att *
228mailimap_fetch_att_new_internaldate(void);
229
230
231/*
232 this function creates a mailimap_fetch_att structure to request
233 text part of a message
234*/
235
236struct mailimap_fetch_att *
237mailimap_fetch_att_new_rfc822(void);
238
239
240/*
241 this function creates a mailimap_fetch_att structure to request
242 header of a message
243*/
244
245struct mailimap_fetch_att *
246mailimap_fetch_att_new_rfc822_header(void);
247
248/*
249 this function creates a mailimap_fetch_att structure to request
250 size of a message
251*/
252
253struct mailimap_fetch_att *
254mailimap_fetch_att_new_rfc822_size(void);
255
256/*
257 this function creates a mailimap_fetch_att structure to request
258 envelope of a message
259*/
260
261struct mailimap_fetch_att *
262mailimap_fetch_att_new_rfc822_text(void);
263
264/*
265 this function creates a mailimap_fetch_att structure to request
266 the MIME structure of a message
267*/
268
269struct mailimap_fetch_att *
270mailimap_fetch_att_new_body(void);
271
272/*
273 this function creates a mailimap_fetch_att structure to request
274 the MIME structure of a message and additional MIME information
275*/
276
277struct mailimap_fetch_att *
278mailimap_fetch_att_new_bodystructure(void);
279
280/*
281 this function creates a mailimap_fetch_att structure to request
282 unique identifier of a message
283*/
284
285struct mailimap_fetch_att *
286mailimap_fetch_att_new_uid(void);
287
288/*
289 this function creates a mailimap_fetch_att structure to request
290 a given section of a message
291*/
292
293struct mailimap_fetch_att *
294mailimap_fetch_att_new_body_section(struct mailimap_section * section);
295
296/*
297 this function creates a mailimap_fetch_att structure to request
298 a given section of a message without marking it as read
299*/
300
301struct mailimap_fetch_att *
302mailimap_fetch_att_new_body_peek_section(struct mailimap_section * section);
303
304/*
305 this function creates a mailimap_fetch_att structure to request
306 a part of a section of a message
307*/
308
309struct mailimap_fetch_att *
310mailimap_fetch_att_new_body_section_partial(struct mailimap_section * section,
311 uint32_t offset, uint32_t size);
312
313/*
314 this function creates a mailimap_fetch_att structure to request
315 a part of a section of a message without marking it as read
316*/
317
318struct mailimap_fetch_att *
319mailimap_fetch_att_new_body_peek_section_partial(struct mailimap_section * section,
320 uint32_t offset, uint32_t size);
321
322/*
323 this function creates a mailimap_fetch_type structure to request
324 (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE) of a message
325*/
326
327struct mailimap_fetch_type *
328mailimap_fetch_type_new_all(void);
329
330/*
331 this function creates a mailimap_fetch_type structure to request
332 (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY)
333*/
334
335struct mailimap_fetch_type *
336mailimap_fetch_type_new_full(void);
337
338/*
339 this function creates a mailimap_fetch_type structure to request
340 (FLAGS INTERNALDATE RFC822.SIZE)
341*/
342
343struct mailimap_fetch_type *
344mailimap_fetch_type_new_fast(void);
345
346/*
347 this function creates a mailimap_fetch_type structure to request
348 the given fetch attribute
349*/
350
351struct mailimap_fetch_type *
352mailimap_fetch_type_new_fetch_att(struct mailimap_fetch_att * fetch_att);
353
354/*
355 this function creates a mailimap_fetch_type structure to request
356 the list of fetch attributes
357*/
358
359struct mailimap_fetch_type *
360mailimap_fetch_type_new_fetch_att_list(clist * fetch_att_list);
361
362/*
363 this function creates a mailimap_fetch_type structure
364*/
365
366struct mailimap_fetch_type *
367mailimap_fetch_type_new_fetch_att_list_empty(void);
368
369/*
370 this function adds a given fetch attribute to the mailimap_fetch
371 structure
372
373 @return MAILIMAP_NO_ERROR will be returned on success,
374 other code will be returned otherwise
375*/
376
377int
378mailimap_fetch_type_new_fetch_att_list_add(struct mailimap_fetch_type *
379 fetch_type,
380 struct mailimap_fetch_att *
381 fetch_att);
382
383/*
384 this function creates a store attribute to set the given flags
385*/
386
387struct mailimap_store_att_flags *
388mailimap_store_att_flags_new_set_flags(struct mailimap_flag_list * flags);
389
390/*
391 this function creates a store attribute to silently set the given flags
392*/
393
394struct mailimap_store_att_flags *
395mailimap_store_att_flags_new_set_flags_silent(struct mailimap_flag_list *
396 flags);
397
398/*
399 this function creates a store attribute to add the given flags
400*/
401
402struct mailimap_store_att_flags *
403mailimap_store_att_flags_new_add_flags(struct mailimap_flag_list * flags);
404
405/*
406 this function creates a store attribute to add silently the given flags
407*/
408
409struct mailimap_store_att_flags *
410mailimap_store_att_flags_new_add_flags_silent(struct mailimap_flag_list *
411 flags);
412
413/*
414 this function creates a store attribute to remove the given flags
415*/
416
417struct mailimap_store_att_flags *
418mailimap_store_att_flags_new_remove_flags(struct mailimap_flag_list * flags);
419
420/*
421 this function creates a store attribute to remove silently the given flags
422*/
423
424struct mailimap_store_att_flags *
425mailimap_store_att_flags_new_remove_flags_silent(struct mailimap_flag_list *
426 flags);
427
428
429/*
430 this function creates a condition structure to match all messages
431*/
432
433struct mailimap_search_key *
434mailimap_search_key_new_all(void);
435
436/*
437 this function creates a condition structure to match messages with Bcc field
438
439 @param bcc this is the content of Bcc to match, it should be allocated
440 with malloc()
441*/
442
443struct mailimap_search_key *
444mailimap_search_key_new_bcc(char * sk_bcc);
445
446/*
447 this function creates a condition structure to match messages with
448 internal date
449*/
450
451struct mailimap_search_key *
452mailimap_search_key_new_before(struct mailimap_date * sk_before);
453
454/*
455 this function creates a condition structure to match messages with
456 message content
457
458 @param body this is the content of the message to match, it should
459 be allocated with malloc()
460*/
461
462struct mailimap_search_key *
463mailimap_search_key_new_body(char * sk_body);
464
465/*
466 this function creates a condition structure to match messages with
467 Cc field
468
469
470 @param cc this is the content of Cc to match, it should be allocated
471 with malloc()
472*/
473
474struct mailimap_search_key *
475mailimap_search_key_new_cc(char * sk_cc);
476
477/*
478 this function creates a condition structure to match messages with
479 From field
480
481 @param from this is the content of From to match, it should be allocated
482 with malloc()
483*/
484
485struct mailimap_search_key *
486mailimap_search_key_new_from(char * sk_from);
487
488/*
489 this function creates a condition structure to match messages with
490 a flag given by keyword
491*/
492
493struct mailimap_search_key *
494mailimap_search_key_new_keyword(char * sk_keyword);
495
496/*
497 this function creates a condition structure to match messages with
498 internal date
499*/
500
501struct mailimap_search_key *
502mailimap_search_key_new_on(struct mailimap_date * sk_on);
503
504/*
505 this function creates a condition structure to match messages with
506 internal date
507*/
508
509struct mailimap_search_key *
510mailimap_search_key_new_since(struct mailimap_date * sk_since);
511
512/*
513 this function creates a condition structure to match messages with
514 Subject field
515
516 @param subject this is the content of Subject to match, it should
517 be allocated with malloc()
518*/
519
520struct mailimap_search_key *
521mailimap_search_key_new_subject(char * sk_subject);
522
523/*
524 this function creates a condition structure to match messages with
525 message text part
526
527 @param text this is the message text to match, it should
528 be allocated with malloc()
529*/
530
531struct mailimap_search_key *
532mailimap_search_key_new_text(char * sk_text);
533
534/*
535 this function creates a condition structure to match messages with
536 To field
537
538 @param to this is the content of To to match, it should be allocated
539 with malloc()
540*/
541
542struct mailimap_search_key *
543mailimap_search_key_new_to(char * sk_to);
544
545/*
546 this function creates a condition structure to match messages with
547 no a flag given by unkeyword
548*/
549
550struct mailimap_search_key *
551mailimap_search_key_new_unkeyword(char * sk_unkeyword);
552
553/*
554 this function creates a condition structure to match messages with
555 the given field
556
557 @param header_name this is the name of the field to match, it
558 should be allocated with malloc()
559
560 @param header_value this is the content, it should be allocated
561 with malloc()
562*/
563
564struct mailimap_search_key *
565mailimap_search_key_new_header(char * sk_header_name, char * sk_header_value);
566
567
568/*
569 this function creates a condition structure to match messages with size
570*/
571
572struct mailimap_search_key *
573mailimap_search_key_new_larger(uint32_t sk_larger);
574
575/*
576 this function creates a condition structure to match messages that
577 do not match the given condition
578*/
579
580struct mailimap_search_key *
581mailimap_search_key_new_not(struct mailimap_search_key * sk_not);
582
583/*
584 this function creates a condition structure to match messages that
585 match one of the given conditions
586*/
587
588struct mailimap_search_key *
589mailimap_search_key_new_or(struct mailimap_search_key * sk_or1,
590 struct mailimap_search_key * sk_or2);
591
592/*
593 this function creates a condition structure to match messages
594 with Date field
595*/
596
597struct mailimap_search_key *
598mailimap_search_key_new_sentbefore(struct mailimap_date * sk_sentbefore);
599
600/*
601 this function creates a condition structure to match messages
602 with Date field
603*/
604
605struct mailimap_search_key *
606mailimap_search_key_new_senton(struct mailimap_date * sk_senton);
607
608/*
609 this function creates a condition structure to match messages
610 with Date field
611*/
612
613struct mailimap_search_key *
614mailimap_search_key_new_sentsince(struct mailimap_date * sk_sentsince);
615
616/*
617 this function creates a condition structure to match messages with size
618*/
619
620struct mailimap_search_key *
621mailimap_search_key_new_smaller(uint32_t sk_smaller);
622
623/*
624 this function creates a condition structure to match messages with unique
625 identifier
626*/
627
628struct mailimap_search_key *
629mailimap_search_key_new_uid(struct mailimap_set * sk_uid);
630
631/*
632 this function creates a condition structure to match messages with number
633 or unique identifier (depending whether SEARCH or UID SEARCH is used)
634*/
635
636struct mailimap_search_key *
637mailimap_search_key_new_set(struct mailimap_set * sk_set);
638
639/*
640 this function creates a condition structure to match messages that match
641 all the conditions given in the list
642*/
643
644struct mailimap_search_key *
645mailimap_search_key_new_multiple(clist * sk_multiple);
646
647
648/*
649 same as previous but the list is empty
650*/
651
652struct mailimap_search_key *
653mailimap_search_key_new_multiple_empty(void);
654
655/*
656 this function adds a condition to the condition list
657
658 @return MAILIMAP_NO_ERROR will be returned on success,
659 other code will be returned otherwise
660*/
661
662int
663mailimap_search_key_multiple_add(struct mailimap_search_key * keys,
664 struct mailimap_search_key * key_item);
665
666
667/*
668 this function creates an empty list of flags
669*/
670
671struct mailimap_flag_list *
672mailimap_flag_list_new_empty(void);
673
674/*
675 this function adds a flag to the list of flags
676
677 @return MAILIMAP_NO_ERROR will be returned on success,
678 other code will be returned otherwise
679*/
680
681int mailimap_flag_list_add(struct mailimap_flag_list * flag_list,
682 struct mailimap_flag * f);
683
684/*
685 this function creates a \Answered flag
686*/
687
688struct mailimap_flag * mailimap_flag_new_answered(void);
689
690/*
691 this function creates a \Flagged flag
692*/
693
694struct mailimap_flag * mailimap_flag_new_flagged(void);
695
696/*
697 this function creates a \Deleted flag
698*/
699
700struct mailimap_flag * mailimap_flag_new_deleted(void);
701
702/*
703 this function creates a \Seen flag
704*/
705
706struct mailimap_flag * mailimap_flag_new_seen(void);
707
708/*
709 this function creates a \Draft flag
710*/
711
712struct mailimap_flag * mailimap_flag_new_draft(void);
713
714/*
715 this function creates a keyword flag
716
717 @param flag_keyword this should be allocated with malloc()
718*/
719
720struct mailimap_flag * mailimap_flag_new_flag_keyword(char * flag_keyword);
721
722
723/*
724 this function creates an extension flag
725
726 @param flag_extension this should be allocated with malloc()
727*/
728
729struct mailimap_flag * mailimap_flag_new_flag_extension(char * flag_extension);
730
731/*
732 this function creates an empty list of status attributes
733*/
734
735struct mailimap_status_att_list * mailimap_status_att_list_new_empty(void);
736
737/*
738 this function adds status attributes to the list
739
740 @return MAILIMAP_NO_ERROR will be returned on success,
741 other code will be returned otherwise
742*/
743
744int
745mailimap_status_att_list_add(struct mailimap_status_att_list * sa_list,
746 int status_att);
747
748/* return mailimap_section_part from a given mailimap_body */
749
750int mailimap_get_section_part_from_body(struct mailimap_body * root_part,
751 struct mailimap_body * part,
752 struct mailimap_section_part ** result);
753
754#ifdef __cplusplus
755}
756#endif
757
758#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailimf.h b/kmicromail/libetpan/include/libetpan/mailimf.h
new file mode 100644
index 0000000..3248e73
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailimf.h
@@ -0,0 +1,345 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMF_H
37
38#define MAILIMF_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailimf_types.h>
45#include <libetpan/mailimf_write.h>
46#include <libetpan/mailimf_types_helper.h>
47
48#include <inttypes.h>
49#include <sys/types.h>
50
51/*
52 mailimf_message_parse will parse the given message
53
54 @param message this is a string containing the message content
55 @param length this is the size of the given string
56 @param index this is a pointer to the start of the message in
57 the given string, (* index) is modified to point at the end
58 of the parsed data
59 @param result the result of the parse operation is stored in
60 (* result)
61
62 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
63*/
64
65int mailimf_message_parse(const char * message, size_t length,
66 size_t * index,
67 struct mailimf_message ** result);
68
69/*
70 mailimf_body_parse will parse the given text part of a message
71
72 @param message this is a string containing the message text part
73 @param length this is the size of the given string
74 @param index this is a pointer to the start of the message text part in
75 the given string, (* index) is modified to point at the end
76 of the parsed data
77 @param result the result of the parse operation is stored in
78 (* result)
79
80 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
81*/
82
83int mailimf_body_parse(const char * message, size_t length,
84 size_t * index,
85 struct mailimf_body ** result);
86
87/*
88 mailimf_fields_parse will parse the given header fields
89
90 @param message this is a string containing the header fields
91 @param length this is the size of the given string
92 @param index this is a pointer to the start of the header fields in
93 the given string, (* index) is modified to point at the end
94 of the parsed data
95 @param result the result of the parse operation is stored in
96 (* result)
97
98 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
99*/
100
101int mailimf_fields_parse(const char * message, size_t length,
102 size_t * index,
103 struct mailimf_fields ** result);
104
105/*
106 mailimf_mailbox_list_parse will parse the given mailbox list
107
108 @param message this is a string containing the mailbox list
109 @param length this is the size of the given string
110 @param index this is a pointer to the start of the mailbox list in
111 the given string, (* index) is modified to point at the end
112 of the parsed data
113 @param result the result of the parse operation is stored in
114 (* result)
115
116 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
117*/
118
119int
120mailimf_mailbox_list_parse(const char * message, size_t length,
121 size_t * index,
122 struct mailimf_mailbox_list ** result);
123
124/*
125 mailimf_address_list_parse will parse the given address list
126
127 @param message this is a string containing the address list
128 @param length this is the size of the given string
129 @param index this is a pointer to the start of the address list in
130 the given string, (* index) is modified to point at the end
131 of the parsed data
132 @param result the result of the parse operation is stored in
133 (* result)
134
135 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
136*/
137
138int
139mailimf_address_list_parse(const char * message, size_t length,
140 size_t * index,
141 struct mailimf_address_list ** result);
142
143/*
144 mailimf_address_parse will parse the given address
145
146 @param message this is a string containing the address
147 @param length this is the size of the given string
148 @param index this is a pointer to the start of the address in
149 the given string, (* index) is modified to point at the end
150 of the parsed data
151 @param result the result of the parse operation is stored in
152 (* result)
153
154 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
155*/
156
157int mailimf_address_parse(const char * message, size_t length,
158 size_t * index,
159 struct mailimf_address ** result);
160
161/*
162 mailimf_mailbox_parse will parse the given address
163
164 @param message this is a string containing the mailbox
165 @param length this is the size of the given string
166 @param index this is a pointer to the start of the mailbox in
167 the given string, (* index) is modified to point at the end
168 of the parsed data
169 @param result the result of the parse operation is stored in
170 (* result)
171
172 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
173*/
174
175int mailimf_mailbox_parse(const char * message, size_t length,
176 size_t * index,
177 struct mailimf_mailbox ** result);
178
179/*
180 mailimf_date_time_parse will parse the given RFC 2822 date
181
182 @param message this is a string containing the date
183 @param length this is the size of the given string
184 @param index this is a pointer to the start of the date in
185 the given string, (* index) is modified to point at the end
186 of the parsed data
187 @param result the result of the parse operation is stored in
188 (* result)
189
190 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
191*/
192
193int mailimf_date_time_parse(const char * message, size_t length,
194 size_t * index,
195 struct mailimf_date_time ** result);
196
197/*
198 mailimf_envelope_fields_parse will parse the given fields (Date,
199 From, Sender, Reply-To, To, Cc, Bcc, Message-ID, In-Reply-To,
200 References and Subject)
201
202 @param message this is a string containing the header fields
203 @param length this is the size of the given string
204 @param index this is a pointer to the start of the header fields in
205 the given string, (* index) is modified to point at the end
206 of the parsed data
207 @param result the result of the parse operation is stored in
208 (* result)
209
210 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
211*/
212
213int mailimf_envelope_fields_parse(const char * message, size_t length,
214 size_t * index,
215 struct mailimf_fields ** result);
216
217/*
218 mailimf_ignore_field_parse will skip the given field
219
220 @param message this is a string containing the header field
221 @param length this is the size of the given string
222 @param index this is a pointer to the start of the header field in
223 the given string, (* index) is modified to point at the end
224 of the parsed data
225
226 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
227*/
228
229
230int mailimf_ignore_field_parse(const char * message, size_t length,
231 size_t * index);
232
233/*
234 mailimf_envelope_fields will parse the given fields (Date,
235 From, Sender, Reply-To, To, Cc, Bcc, Message-ID, In-Reply-To,
236 References and Subject), other fields will be added as optional
237 fields.
238
239 @param message this is a string containing the header fields
240 @param length this is the size of the given string
241 @param index this is a pointer to the start of the header fields in
242 the given string, (* index) is modified to point at the end
243 of the parsed data
244 @param result the result of the parse operation is stored in
245 (* result)
246
247 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
248*/
249
250
251int
252mailimf_envelope_and_optional_fields_parse(const char * message, size_t length,
253 size_t * index,
254 struct mailimf_fields ** result);
255
256/*
257 mailimf_envelope_fields will parse the given fields as optional
258 fields.
259
260 @param message this is a string containing the header fields
261 @param length this is the size of the given string
262 @param index this is a pointer to the start of the header fields in
263 the given string, (* index) is modified to point at the end
264 of the parsed data
265 @param result the result of the parse operation is stored in
266 (* result)
267
268 @return MAILIMF_NO_ERROR on success, MAILIMF_ERROR_XXX on error
269*/
270
271int
272mailimf_optional_fields_parse(const char * message, size_t length,
273 size_t * index,
274 struct mailimf_fields ** result);
275
276
277/* internal use, exported for MIME */
278
279int mailimf_fws_parse(const char * message, size_t length, size_t * index);
280
281int mailimf_cfws_parse(const char * message, size_t length,
282 size_t * index);
283
284int mailimf_char_parse(const char * message, size_t length,
285 size_t * index, char token);
286
287int mailimf_unstrict_char_parse(const char * message, size_t length,
288 size_t * index, char token);
289
290int mailimf_crlf_parse(const char * message, size_t length, size_t * index);
291
292int
293mailimf_custom_string_parse(const char * message, size_t length,
294 size_t * index, char ** result,
295 int (* is_custom_char)(char));
296
297int
298mailimf_token_case_insensitive_len_parse(const char * message, size_t length,
299 size_t * index, char * token,
300 size_t token_length);
301
302#define mailimf_token_case_insensitive_parse(message, length, index, token) \
303 mailimf_token_case_insensitive_len_parse(message, length, index, token, \
304 sizeof(token) - 1)
305
306int mailimf_quoted_string_parse(const char * message, size_t length,
307 size_t * index, char ** result);
308
309int
310mailimf_number_parse(const char * message, size_t length,
311 size_t * index, uint32_t * result);
312
313int mailimf_msg_id_parse(const char * message, size_t length,
314 size_t * index,
315 char ** result);
316
317int mailimf_msg_id_list_parse(const char * message, size_t length,
318 size_t * index, clist ** result);
319
320int mailimf_word_parse(const char * message, size_t length,
321 size_t * index, char ** result);
322
323int mailimf_atom_parse(const char * message, size_t length,
324 size_t * index, char ** result);
325
326int mailimf_fws_atom_parse(const char * message, size_t length,
327 size_t * index, char ** result);
328
329int mailimf_fws_word_parse(const char * message, size_t length,
330 size_t * index, char ** result);
331
332int mailimf_fws_quoted_string_parse(const char * message, size_t length,
333 size_t * index, char ** result);
334
335/* exported for IMAP */
336
337int mailimf_references_parse(const char * message, size_t length,
338 size_t * index,
339 struct mailimf_references ** result);
340
341#ifdef __cplusplus
342}
343#endif
344
345#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailimf_types.h b/kmicromail/libetpan/include/libetpan/mailimf_types.h
new file mode 100644
index 0000000..288feb6
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailimf_types.h
@@ -0,0 +1,793 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32
33/*
34 * $Id$
35 */
36
37#ifndef MAILIMF_TYPES_H
38
39#define MAILIMF_TYPES_H
40
41#ifdef __cplusplus
42extern "C" {
43#endif
44
45#include <libetpan/clist.h>
46#include <sys/types.h>
47
48/*
49 IMPORTANT NOTE:
50
51 All allocation functions will take as argument allocated data
52 and will store these data in the structure they will allocate.
53 Data should be persistant during all the use of the structure
54 and will be freed by the free function of the structure
55
56 allocation functions will return NULL on failure
57*/
58
59/*
60 mailimf_date_time is a date
61
62 - day is the day of month (1 to 31)
63
64 - month (1 to 12)
65
66 - year (4 digits)
67
68 - hour (0 to 23)
69
70 - min (0 to 59)
71
72 - sec (0 to 59)
73
74 - zone (this is the decimal value that we can read, for example:
75 for "-0200", the value is -200)
76*/
77
78struct mailimf_date_time {
79 int dt_day;
80 int dt_month;
81 int dt_year;
82 int dt_hour;
83 int dt_min;
84 int dt_sec;
85 int dt_zone;
86};
87
88struct mailimf_date_time *
89mailimf_date_time_new(int dt_day, int dt_month, int dt_year,
90 int dt_hour, int dt_min, int dt_sec, int dt_zone);
91
92void mailimf_date_time_free(struct mailimf_date_time * date_time);
93
94
95
96/* this is the type of address */
97
98enum {
99 MAILIMF_ADDRESS_ERROR, /* on parse error */
100 MAILIMF_ADDRESS_MAILBOX, /* if this is a mailbox (mailbox@domain) */
101 MAILIMF_ADDRESS_GROUP, /* if this is a group
102 (group_name: address1@domain1,
103 address2@domain2; ) */
104};
105
106/*
107 mailimf_address is an address
108
109 - type can be MAILIMF_ADDRESS_MAILBOX or MAILIMF_ADDRESS_GROUP
110
111 - mailbox is a mailbox if type is MAILIMF_ADDRESS_MAILBOX
112
113 - group is a group if type is MAILIMF_ADDRESS_GROUP
114*/
115
116struct mailimf_address {
117 int ad_type;
118 union {
119 struct mailimf_mailbox * ad_mailbox; /* can be NULL */
120 struct mailimf_group * ad_group; /* can be NULL */
121 } ad_data;
122};
123
124
125struct mailimf_address *
126mailimf_address_new(int ad_type, struct mailimf_mailbox * ad_mailbox,
127 struct mailimf_group * ad_group);
128
129void mailimf_address_free(struct mailimf_address * address);
130
131
132
133/*
134 mailimf_mailbox is a mailbox
135
136 - display_name is the name that will be displayed for this mailbox,
137 for example 'name' in '"name" <mailbox@domain>,
138 should be allocated with malloc()
139
140 - addr_spec is the mailbox, for example 'mailbox@domain'
141 in '"name" <mailbox@domain>, should be allocated with malloc()
142*/
143
144struct mailimf_mailbox {
145 char * mb_display_name; /* can be NULL */
146 char * mb_addr_spec; /* != NULL */
147};
148
149struct mailimf_mailbox *
150mailimf_mailbox_new(char * mb_display_name, char * mb_addr_spec);
151
152void mailimf_mailbox_free(struct mailimf_mailbox * mailbox);
153
154
155
156/*
157 mailimf_group is a group
158
159 - display_name is the name that will be displayed for this group,
160 for example 'group_name' in
161 'group_name: address1@domain1, address2@domain2;', should be allocated
162 with malloc()
163
164 - mb_list is a list of mailboxes
165*/
166
167struct mailimf_group {
168 char * grp_display_name; /* != NULL */
169 struct mailimf_mailbox_list * grp_mb_list; /* can be NULL */
170};
171
172struct mailimf_group *
173mailimf_group_new(char * grp_display_name,
174 struct mailimf_mailbox_list * grp_mb_list);
175
176void mailimf_group_free(struct mailimf_group * group);
177
178
179
180/*
181 mailimf_mailbox_list is a list of mailboxes
182
183 - list is a list of mailboxes
184*/
185
186struct mailimf_mailbox_list {
187 clist * mb_list; /* list of (struct mailimf_mailbox *), != NULL */
188};
189
190struct mailimf_mailbox_list *
191mailimf_mailbox_list_new(clist * mb_list);
192
193void mailimf_mailbox_list_free(struct mailimf_mailbox_list * mb_list);
194
195
196
197/*
198 mailimf_address_list is a list of addresses
199
200 - list is a list of addresses
201*/
202
203struct mailimf_address_list {
204 clist * ad_list; /* list of (struct mailimf_address *), != NULL */
205};
206
207struct mailimf_address_list *
208mailimf_address_list_new(clist * ad_list);
209
210void mailimf_address_list_free(struct mailimf_address_list * addr_list);
211
212
213
214
215
216/*
217 mailimf_body is the text part of a message
218
219 - text is the beginning of the text part, it is a substring
220 of an other string
221
222 - size is the size of the text part
223*/
224
225struct mailimf_body {
226 const char * bd_text; /* != NULL */
227 size_t bd_size;
228};
229
230struct mailimf_body * mailimf_body_new(const char * bd_text, size_t bd_size);
231
232void mailimf_body_free(struct mailimf_body * body);
233
234
235
236
237/*
238 mailimf_message is the content of the message
239
240 - msg_fields is the header fields of the message
241
242 - msg_body is the text part of the message
243*/
244
245struct mailimf_message {
246 struct mailimf_fields * msg_fields; /* != NULL */
247 struct mailimf_body * msg_body; /* != NULL */
248};
249
250struct mailimf_message *
251mailimf_message_new(struct mailimf_fields * msg_fields,
252 struct mailimf_body * msg_body);
253
254void mailimf_message_free(struct mailimf_message * message);
255
256
257
258
259/*
260 mailimf_fields is a list of header fields
261
262 - fld_list is a list of header fields
263*/
264
265struct mailimf_fields {
266 clist * fld_list; /* list of (struct mailimf_field *), != NULL */
267};
268
269struct mailimf_fields * mailimf_fields_new(clist * fld_list);
270
271void mailimf_fields_free(struct mailimf_fields * fields);
272
273
274
275/* this is a type of field */
276
277enum {
278 MAILIMF_FIELD_NONE, /* on parse error */
279 MAILIMF_FIELD_RETURN_PATH, /* Return-Path */
280 MAILIMF_FIELD_RESENT_DATE, /* Resent-Date */
281 MAILIMF_FIELD_RESENT_FROM, /* Resent-From */
282 MAILIMF_FIELD_RESENT_SENDER, /* Resent-Sender */
283 MAILIMF_FIELD_RESENT_TO, /* Resent-To */
284 MAILIMF_FIELD_RESENT_CC, /* Resent-Cc */
285 MAILIMF_FIELD_RESENT_BCC, /* Resent-Bcc */
286 MAILIMF_FIELD_RESENT_MSG_ID, /* Resent-Message-ID */
287 MAILIMF_FIELD_ORIG_DATE, /* Date */
288 MAILIMF_FIELD_FROM, /* From */
289 MAILIMF_FIELD_SENDER, /* Sender */
290 MAILIMF_FIELD_REPLY_TO, /* Reply-To */
291 MAILIMF_FIELD_TO, /* To */
292 MAILIMF_FIELD_CC, /* Cc */
293 MAILIMF_FIELD_BCC, /* Bcc */
294 MAILIMF_FIELD_MESSAGE_ID, /* Message-ID */
295 MAILIMF_FIELD_IN_REPLY_TO, /* In-Reply-To */
296 MAILIMF_FIELD_REFERENCES, /* References */
297 MAILIMF_FIELD_SUBJECT, /* Subject */
298 MAILIMF_FIELD_COMMENTS, /* Comments */
299 MAILIMF_FIELD_KEYWORDS, /* Keywords */
300 MAILIMF_FIELD_OPTIONAL_FIELD, /* other field */
301};
302
303/*
304 mailimf_field is a field
305
306 - fld_type is the type of the field
307
308 - fld_data.fld_return_path is the parsed content of the Return-Path
309 field if type is MAILIMF_FIELD_RETURN_PATH
310
311 - fld_data.fld_resent_date is the parsed content of the Resent-Date field
312 if type is MAILIMF_FIELD_RESENT_DATE
313
314 - fld_data.fld_resent_from is the parsed content of the Resent-From field
315
316 - fld_data.fld_resent_sender is the parsed content of the Resent-Sender field
317
318 - fld_data.fld_resent_to is the parsed content of the Resent-To field
319
320 - fld_data.fld_resent_cc is the parsed content of the Resent-Cc field
321
322 - fld_data.fld_resent_bcc is the parsed content of the Resent-Bcc field
323
324 - fld_data.fld_resent_msg_id is the parsed content of the Resent-Message-ID
325 field
326
327 - fld_data.fld_orig_date is the parsed content of the Date field
328
329 - fld_data.fld_from is the parsed content of the From field
330
331 - fld_data.fld_sender is the parsed content of the Sender field
332
333 - fld_data.fld_reply_to is the parsed content of the Reply-To field
334
335 - fld_data.fld_to is the parsed content of the To field
336
337 - fld_data.fld_cc is the parsed content of the Cc field
338
339 - fld_data.fld_bcc is the parsed content of the Bcc field
340
341 - fld_data.fld_message_id is the parsed content of the Message-ID field
342
343 - fld_data.fld_in_reply_to is the parsed content of the In-Reply-To field
344
345 - fld_data.fld_references is the parsed content of the References field
346
347 - fld_data.fld_subject is the content of the Subject field
348
349 - fld_data.fld_comments is the content of the Comments field
350
351 - fld_data.fld_keywords is the parsed content of the Keywords field
352
353 - fld_data.fld_optional_field is an other field and is not parsed
354*/
355
356#define LIBETPAN_MAILIMF_FIELD_UNION
357
358struct mailimf_field {
359 int fld_type;
360 union {
361 struct mailimf_return * fld_return_path; /* can be NULL */
362 struct mailimf_orig_date * fld_resent_date; /* can be NULL */
363 struct mailimf_from * fld_resent_from; /* can be NULL */
364 struct mailimf_sender * fld_resent_sender; /* can be NULL */
365 struct mailimf_to * fld_resent_to; /* can be NULL */
366 struct mailimf_cc * fld_resent_cc; /* can be NULL */
367 struct mailimf_bcc * fld_resent_bcc; /* can be NULL */
368 struct mailimf_message_id * fld_resent_msg_id; /* can be NULL */
369 struct mailimf_orig_date * fld_orig_date; /* can be NULL */
370 struct mailimf_from * fld_from; /* can be NULL */
371 struct mailimf_sender * fld_sender; /* can be NULL */
372 struct mailimf_reply_to * fld_reply_to; /* can be NULL */
373 struct mailimf_to * fld_to; /* can be NULL */
374 struct mailimf_cc * fld_cc; /* can be NULL */
375 struct mailimf_bcc * fld_bcc; /* can be NULL */
376 struct mailimf_message_id * fld_message_id; /* can be NULL */
377 struct mailimf_in_reply_to * fld_in_reply_to; /* can be NULL */
378 struct mailimf_references * fld_references; /* can be NULL */
379 struct mailimf_subject * fld_subject; /* can be NULL */
380 struct mailimf_comments * fld_comments; /* can be NULL */
381 struct mailimf_keywords * fld_keywords; /* can be NULL */
382 struct mailimf_optional_field * fld_optional_field; /* can be NULL */
383 } fld_data;
384};
385
386struct mailimf_field *
387mailimf_field_new(int fld_type,
388 struct mailimf_return * fld_return_path,
389 struct mailimf_orig_date * fld_resent_date,
390 struct mailimf_from * fld_resent_from,
391 struct mailimf_sender * fld_resent_sender,
392 struct mailimf_to * fld_resent_to,
393 struct mailimf_cc * fld_resent_cc,
394 struct mailimf_bcc * fld_resent_bcc,
395 struct mailimf_message_id * fld_resent_msg_id,
396 struct mailimf_orig_date * fld_orig_date,
397 struct mailimf_from * fld_from,
398 struct mailimf_sender * fld_sender,
399 struct mailimf_reply_to * fld_reply_to,
400 struct mailimf_to * fld_to,
401 struct mailimf_cc * fld_cc,
402 struct mailimf_bcc * fld_bcc,
403 struct mailimf_message_id * fld_message_id,
404 struct mailimf_in_reply_to * fld_in_reply_to,
405 struct mailimf_references * fld_references,
406 struct mailimf_subject * fld_subject,
407 struct mailimf_comments * fld_comments,
408 struct mailimf_keywords * fld_keywords,
409 struct mailimf_optional_field * fld_optional_field);
410
411void mailimf_field_free(struct mailimf_field * field);
412
413
414
415/*
416 mailimf_orig_date is the parsed Date field
417
418 - date_time is the parsed date
419*/
420
421struct mailimf_orig_date {
422 struct mailimf_date_time * dt_date_time; /* != NULL */
423};
424
425struct mailimf_orig_date * mailimf_orig_date_new(struct mailimf_date_time *
426 dt_date_time);
427
428void mailimf_orig_date_free(struct mailimf_orig_date * orig_date);
429
430
431
432
433/*
434 mailimf_from is the parsed From field
435
436 - mb_list is the parsed mailbox list
437*/
438
439struct mailimf_from {
440 struct mailimf_mailbox_list * frm_mb_list; /* != NULL */
441};
442
443struct mailimf_from *
444mailimf_from_new(struct mailimf_mailbox_list * frm_mb_list);
445
446void mailimf_from_free(struct mailimf_from * from);
447
448
449
450/*
451 mailimf_sender is the parsed Sender field
452
453 - snd_mb is the parsed mailbox
454*/
455
456struct mailimf_sender {
457 struct mailimf_mailbox * snd_mb; /* != NULL */
458};
459
460struct mailimf_sender * mailimf_sender_new(struct mailimf_mailbox * snd_mb);
461
462void mailimf_sender_free(struct mailimf_sender * sender);
463
464
465
466
467/*
468 mailimf_reply_to is the parsed Reply-To field
469
470 - rt_addr_list is the parsed address list
471 */
472
473struct mailimf_reply_to {
474 struct mailimf_address_list * rt_addr_list; /* != NULL */
475};
476
477struct mailimf_reply_to *
478mailimf_reply_to_new(struct mailimf_address_list * rt_addr_list);
479
480void mailimf_reply_to_free(struct mailimf_reply_to * reply_to);
481
482
483
484
485/*
486 mailimf_to is the parsed To field
487
488 - to_addr_list is the parsed address list
489*/
490
491struct mailimf_to {
492 struct mailimf_address_list * to_addr_list; /* != NULL */
493};
494
495struct mailimf_to * mailimf_to_new(struct mailimf_address_list * to_addr_list);
496
497void mailimf_to_free(struct mailimf_to * to);
498
499
500
501
502/*
503 mailimf_cc is the parsed Cc field
504
505 - cc_addr_list is the parsed addres list
506*/
507
508struct mailimf_cc {
509 struct mailimf_address_list * cc_addr_list; /* != NULL */
510};
511
512struct mailimf_cc * mailimf_cc_new(struct mailimf_address_list * cc_addr_list);
513
514void mailimf_cc_free(struct mailimf_cc * cc);
515
516
517
518
519/*
520 mailimf_bcc is the parsed Bcc field
521
522 - bcc_addr_list is the parsed addres list
523*/
524
525struct mailimf_bcc {
526 struct mailimf_address_list * bcc_addr_list; /* can be NULL */
527};
528
529struct mailimf_bcc *
530mailimf_bcc_new(struct mailimf_address_list * bcc_addr_list);
531
532void mailimf_bcc_free(struct mailimf_bcc * bcc);
533
534
535
536/*
537 mailimf_message_id is the parsed Message-ID field
538
539 - mid_value is the message identifier
540*/
541
542struct mailimf_message_id {
543 char * mid_value; /* != NULL */
544};
545
546struct mailimf_message_id * mailimf_message_id_new(char * mid_value);
547
548void mailimf_message_id_free(struct mailimf_message_id * message_id);
549
550
551
552
553/*
554 mailimf_in_reply_to is the parsed In-Reply-To field
555
556 - mid_list is the list of message identifers
557*/
558
559struct mailimf_in_reply_to {
560 clist * mid_list; /* list of (char *), != NULL */
561};
562
563struct mailimf_in_reply_to * mailimf_in_reply_to_new(clist * mid_list);
564
565void mailimf_in_reply_to_free(struct mailimf_in_reply_to * in_reply_to);
566
567
568
569/*
570 mailimf_references is the parsed References field
571
572 - msg_id_list is the list of message identifiers
573 */
574
575struct mailimf_references {
576 clist * mid_list; /* list of (char *) */
577 /* != NULL */
578};
579
580struct mailimf_references * mailimf_references_new(clist * mid_list);
581
582void mailimf_references_free(struct mailimf_references * references);
583
584
585
586/*
587 mailimf_subject is the parsed Subject field
588
589 - sbj_value is the value of the field
590*/
591
592struct mailimf_subject {
593 char * sbj_value; /* != NULL */
594};
595
596struct mailimf_subject * mailimf_subject_new(char * sbj_value);
597
598void mailimf_subject_free(struct mailimf_subject * subject);
599
600
601/*
602 mailimf_comments is the parsed Comments field
603
604 - cm_value is the value of the field
605*/
606
607struct mailimf_comments {
608 char * cm_value; /* != NULL */
609};
610
611struct mailimf_comments * mailimf_comments_new(char * cm_value);
612
613void mailimf_comments_free(struct mailimf_comments * comments);
614
615
616/*
617 mailimf_keywords is the parsed Keywords field
618
619 - kw_list is the list of keywords
620*/
621
622struct mailimf_keywords {
623 clist * kw_list; /* list of (char *), != NULL */
624};
625
626struct mailimf_keywords * mailimf_keywords_new(clist * kw_list);
627
628void mailimf_keywords_free(struct mailimf_keywords * keywords);
629
630
631/*
632 mailimf_return is the parsed Return-Path field
633
634 - ret_path is the parsed value of Return-Path
635*/
636
637struct mailimf_return {
638 struct mailimf_path * ret_path; /* != NULL */
639};
640
641struct mailimf_return *
642mailimf_return_new(struct mailimf_path * ret_path);
643
644void mailimf_return_free(struct mailimf_return * return_path);
645
646
647/*
648 mailimf_path is the parsed value of Return-Path
649
650 - pt_addr_spec is a mailbox
651*/
652
653struct mailimf_path {
654 char * pt_addr_spec; /* can be NULL */
655};
656
657struct mailimf_path * mailimf_path_new(char * pt_addr_spec);
658
659void mailimf_path_free(struct mailimf_path * path);
660
661
662/*
663 mailimf_optional_field is a non-parsed field
664
665 - fld_name is the name of the field
666
667 - fld_value is the value of the field
668*/
669
670struct mailimf_optional_field {
671 char * fld_name; /* != NULL */
672 char * fld_value; /* != NULL */
673};
674
675struct mailimf_optional_field *
676mailimf_optional_field_new(char * fld_name, char * fld_value);
677
678void mailimf_optional_field_free(struct mailimf_optional_field * opt_field);
679
680
681/*
682 mailimf_fields is the native structure that IMF module will use,
683 this module will provide an easier structure to use when parsing fields.
684
685 mailimf_single_fields is an easier structure to get parsed fields,
686 rather than iteration over the list of fields
687
688 - fld_orig_date is the parsed "Date" field
689
690 - fld_from is the parsed "From" field
691
692 - fld_sender is the parsed "Sender "field
693
694 - fld_reply_to is the parsed "Reply-To" field
695
696 - fld_to is the parsed "To" field
697
698 - fld_cc is the parsed "Cc" field
699
700 - fld_bcc is the parsed "Bcc" field
701
702 - fld_message_id is the parsed "Message-ID" field
703
704 - fld_in_reply_to is the parsed "In-Reply-To" field
705
706 - fld_references is the parsed "References" field
707
708 - fld_subject is the parsed "Subject" field
709
710 - fld_comments is the parsed "Comments" field
711
712 - fld_keywords is the parsed "Keywords" field
713*/
714
715struct mailimf_single_fields {
716 struct mailimf_orig_date * fld_orig_date; /* can be NULL */
717 struct mailimf_from * fld_from; /* can be NULL */
718 struct mailimf_sender * fld_sender; /* can be NULL */
719 struct mailimf_reply_to * fld_reply_to; /* can be NULL */
720 struct mailimf_to * fld_to; /* can be NULL */
721 struct mailimf_cc * fld_cc; /* can be NULL */
722 struct mailimf_bcc * fld_bcc; /* can be NULL */
723 struct mailimf_message_id * fld_message_id; /* can be NULL */
724 struct mailimf_in_reply_to * fld_in_reply_to; /* can be NULL */
725 struct mailimf_references * fld_references; /* can be NULL */
726 struct mailimf_subject * fld_subject; /* can be NULL */
727 struct mailimf_comments * fld_comments; /* can be NULL */
728 struct mailimf_keywords * fld_keywords; /* can be NULL */
729};
730
731
732
733
734
735
736/* internal use */
737
738void mailimf_atom_free(char * atom);
739
740void mailimf_dot_atom_free(char * dot_atom);
741
742void mailimf_dot_atom_text_free(char * dot_atom);
743
744void mailimf_quoted_string_free(char * quoted_string);
745
746void mailimf_word_free(char * word);
747
748void mailimf_phrase_free(char * phrase);
749
750void mailimf_unstructured_free(char * unstructured);
751
752void mailimf_angle_addr_free(char * angle_addr);
753
754void mailimf_display_name_free(char * display_name);
755
756void mailimf_addr_spec_free(char * addr_spec);
757
758void mailimf_local_part_free(char * local_part);
759
760void mailimf_domain_free(char * domain);
761
762void mailimf_domain_literal_free(char * domain);
763
764void mailimf_msg_id_free(char * msg_id);
765
766void mailimf_id_left_free(char * id_left);
767
768void mailimf_id_right_free(char * id_right);
769
770void mailimf_no_fold_quote_free(char * nfq);
771
772void mailimf_no_fold_literal_free(char * nfl);
773
774void mailimf_field_name_free(char * field_name);
775
776
777
778/* these are the possible returned error codes */
779
780enum {
781 MAILIMF_NO_ERROR = 0,
782 MAILIMF_ERROR_PARSE,
783 MAILIMF_ERROR_MEMORY,
784 MAILIMF_ERROR_INVAL,
785 MAILIMF_ERROR_FILE,
786};
787
788
789#ifdef __cplusplus
790}
791#endif
792
793#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailimf_types_helper.h b/kmicromail/libetpan/include/libetpan/mailimf_types_helper.h
new file mode 100644
index 0000000..e542b4b
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailimf_types_helper.h
@@ -0,0 +1,370 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMF_TYPES_HELPER
37
38#define MAILIMF_TYPES_HELPER
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailimf_types.h>
45
46/*
47 IMPORTANT NOTE:
48
49 All allocation functions will take as argument allocated data
50 and will store these data in the structure they will allocate.
51 Data should be persistant during all the use of the structure
52 and will be freed by the free function of the structure
53
54 allocation functions will return NULL on failure
55*/
56
57/*
58 mailimf_mailbox_list_new_empty creates an empty list of mailboxes
59*/
60
61struct mailimf_mailbox_list *
62mailimf_mailbox_list_new_empty();
63
64/*
65 mailimf_mailbox_list_add adds a mailbox to the list of mailboxes
66
67 @return MAILIMF_NO_ERROR will be returned on success,
68 other code will be returned otherwise
69*/
70
71int mailimf_mailbox_list_add(struct mailimf_mailbox_list * mailbox_list,
72 struct mailimf_mailbox * mb);
73
74/*
75 mailimf_mailbox_list_add_parse parse the given string
76 into a mailimf_mailbox structure and adds it to the list of mailboxes
77
78 @return MAILIMF_NO_ERROR will be returned on success,
79 other code will be returned otherwise
80*/
81
82int mailimf_mailbox_list_add_parse(struct mailimf_mailbox_list * mailbox_list,
83 char * mb_str);
84
85/*
86 mailimf_mailbox creates a mailimf_mailbox structure with the given
87 arguments and adds it to the list of mailboxes
88
89 - display_name is the name that will be displayed for this mailbox,
90 for example 'name' in '"name" <mailbox@domain>,
91 should be allocated with malloc()
92
93 - address is the mailbox, for example 'mailbox@domain'
94 in '"name" <mailbox@domain>, should be allocated with malloc()
95
96 @return MAILIMF_NO_ERROR will be returned on success,
97 other code will be returned otherwise
98*/
99
100int mailimf_mailbox_list_add_mb(struct mailimf_mailbox_list * mailbox_list,
101 char * display_name, char * address);
102
103/*
104 mailimf_address_list_new_empty creates an empty list of addresses
105*/
106
107struct mailimf_address_list *
108mailimf_address_list_new_empty();
109
110/*
111 mailimf_address_list_add adds a mailbox to the list of addresses
112
113 @return MAILIMF_NO_ERROR will be returned on success,
114 other code will be returned otherwise
115*/
116
117int mailimf_address_list_add(struct mailimf_address_list * address_list,
118 struct mailimf_address * addr);
119
120/*
121 mailimf_address_list_add_parse parse the given string
122 into a mailimf_address structure and adds it to the list of addresses
123
124 @return MAILIMF_NO_ERROR will be returned on success,
125 other code will be returned otherwise
126*/
127
128int mailimf_address_list_add_parse(struct mailimf_address_list * address_list,
129 char * addr_str);
130
131/*
132 mailimf_address_list_add_mb creates a mailbox mailimf_address
133 with the given arguments and adds it to the list of addresses
134
135 - display_name is the name that will be displayed for this mailbox,
136 for example 'name' in '"name" <mailbox@domain>,
137 should be allocated with malloc()
138
139 - address is the mailbox, for example 'mailbox@domain'
140 in '"name" <mailbox@domain>, should be allocated with malloc()
141
142 @return MAILIMF_NO_ERROR will be returned on success,
143 other code will be returned otherwise
144*/
145
146int mailimf_address_list_add_mb(struct mailimf_address_list * address_list,
147 char * display_name, char * address);
148
149/*
150 mailimf_resent_fields_add_data adds a set of resent fields in the
151 given mailimf_fields structure.
152
153 if you don't want a given field in the set to be added in the list
154 of fields, you can give NULL as argument
155
156 @param resent_msg_id sould be allocated with malloc()
157
158 @return MAILIMF_NO_ERROR will be returned on success,
159 other code will be returned otherwise
160*/
161
162int
163mailimf_resent_fields_add_data(struct mailimf_fields * fields,
164 struct mailimf_date_time * resent_date,
165 struct mailimf_mailbox_list * resent_from,
166 struct mailimf_mailbox * resent_sender,
167 struct mailimf_address_list * resent_to,
168 struct mailimf_address_list * resent_cc,
169 struct mailimf_address_list * resent_bcc,
170 char * resent_msg_id);
171
172/*
173 mailimf_resent_fields_new_with_data_all creates a new mailimf_fields
174 structure with a set of resent fields
175
176 if you don't want a given field in the set to be added in the list
177 of fields, you can give NULL as argument
178
179 @param resent_msg_id sould be allocated with malloc()
180
181 @return MAILIMF_NO_ERROR will be returned on success,
182 other code will be returned otherwise
183*/
184
185struct mailimf_fields *
186mailimf_resent_fields_new_with_data_all(struct mailimf_date_time *
187 resent_date, struct mailimf_mailbox_list * resent_from,
188 struct mailimf_mailbox * resent_sender,
189 struct mailimf_address_list * resent_to,
190 struct mailimf_address_list * resent_cc,
191 struct mailimf_address_list * resent_bcc,
192 char * resent_msg_id);
193
194/*
195 mailimf_resent_fields_new_with_data_all creates a new mailimf_fields
196 structure with a set of resent fields.
197 Resent-Date and Resent-Message-ID fields will be generated for you.
198
199 if you don't want a given field in the set to be added in the list
200 of fields, you can give NULL as argument
201
202 @return MAILIMF_NO_ERROR will be returned on success,
203 other code will be returned otherwise
204*/
205
206struct mailimf_fields *
207mailimf_resent_fields_new_with_data(struct mailimf_mailbox_list * from,
208 struct mailimf_mailbox * sender,
209 struct mailimf_address_list * to,
210 struct mailimf_address_list * cc,
211 struct mailimf_address_list * bcc);
212
213/*
214 this function creates a new mailimf_fields structure with no fields
215*/
216
217struct mailimf_fields *
218mailimf_fields_new_empty(void);
219
220
221/*
222 this function adds a field to the mailimf_fields structure
223
224 @return MAILIMF_NO_ERROR will be returned on success,
225 other code will be returned otherwise
226*/
227
228int mailimf_fields_add(struct mailimf_fields * fields,
229 struct mailimf_field * field);
230
231
232/*
233 mailimf_fields_add_data adds a set of fields in the
234 given mailimf_fields structure.
235
236 if you don't want a given field in the set to be added in the list
237 of fields, you can give NULL as argument
238
239 @param msg_id sould be allocated with malloc()
240 @param subject should be allocated with malloc()
241 @param in_reply_to each elements of this list should be allocated
242 with malloc()
243 @param references each elements of this list should be allocated
244 with malloc()
245
246 @return MAILIMF_NO_ERROR will be returned on success,
247 other code will be returned otherwise
248*/
249
250int mailimf_fields_add_data(struct mailimf_fields * fields,
251 struct mailimf_date_time * date,
252 struct mailimf_mailbox_list * from,
253 struct mailimf_mailbox * sender,
254 struct mailimf_address_list * reply_to,
255 struct mailimf_address_list * to,
256 struct mailimf_address_list * cc,
257 struct mailimf_address_list * bcc,
258 char * msg_id,
259 clist * in_reply_to,
260 clist * references,
261 char * subject);
262
263/*
264 mailimf_fields_new_with_data_all creates a new mailimf_fields
265 structure with a set of fields
266
267 if you don't want a given field in the set to be added in the list
268 of fields, you can give NULL as argument
269
270 @param message_id sould be allocated with malloc()
271 @param subject should be allocated with malloc()
272 @param in_reply_to each elements of this list should be allocated
273 with malloc()
274 @param references each elements of this list should be allocated
275 with malloc()
276
277 @return MAILIMF_NO_ERROR will be returned on success,
278 other code will be returned otherwise
279*/
280
281struct mailimf_fields *
282mailimf_fields_new_with_data_all(struct mailimf_date_time * date,
283 struct mailimf_mailbox_list * from,
284 struct mailimf_mailbox * sender,
285 struct mailimf_address_list * reply_to,
286 struct mailimf_address_list * to,
287 struct mailimf_address_list * cc,
288 struct mailimf_address_list * bcc,
289 char * message_id,
290 clist * in_reply_to,
291 clist * references,
292 char * subject);
293
294/*
295 mailimf_fields_new_with_data creates a new mailimf_fields
296 structure with a set of fields
297 Date and Message-ID fields will be generated for you.
298
299 if you don't want a given field in the set to be added in the list
300 of fields, you can give NULL as argument
301
302 @param subject should be allocated with malloc()
303 @param in_reply_to each elements of this list should be allocated
304 with malloc()
305 @param references each elements of this list should be allocated
306 with malloc()
307
308 @return MAILIMF_NO_ERROR will be returned on success,
309 other code will be returned otherwise
310*/
311
312struct mailimf_fields *
313mailimf_fields_new_with_data(struct mailimf_mailbox_list * from,
314 struct mailimf_mailbox * sender,
315 struct mailimf_address_list * reply_to,
316 struct mailimf_address_list * to,
317 struct mailimf_address_list * cc,
318 struct mailimf_address_list * bcc,
319 clist * in_reply_to,
320 clist * references,
321 char * subject);
322
323/*
324 this function returns an allocated message identifier to
325 use in a Message-ID or Resent-Message-ID field
326*/
327
328char * mailimf_get_message_id(void);
329
330/*
331 this function returns a mailimf_date_time structure to
332 use in a Date or Resent-Date field
333*/
334
335struct mailimf_date_time * mailimf_get_current_date(void);
336
337
338/*
339 mailimf_single_fields_init fills a mailimf_single_fields structure
340 with the content of a mailimf_fields structure
341*/
342
343void mailimf_single_fields_init(struct mailimf_single_fields * single_fields,
344 struct mailimf_fields * fields);
345
346/*
347 mailimf_single_fields_new creates a new mailimf_single_fields and
348 fills the structure with mailimf_fields
349*/
350
351struct mailimf_single_fields *
352mailimf_single_fields_new(struct mailimf_fields * fields);
353
354void mailimf_single_fields_free(struct mailimf_single_fields *
355 single_fields);
356
357/*
358 mailimf_field_new_custom creates a new field of type optional
359
360 @param name should be allocated with malloc()
361 @param value should be allocated with malloc()
362*/
363
364struct mailimf_field * mailimf_field_new_custom(char * name, char * value);
365
366#ifdef __cplusplus
367}
368#endif
369
370#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailimf_write.h b/kmicromail/libetpan/include/libetpan/mailimf_write.h
new file mode 100644
index 0000000..b3e61ab
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailimf_write.h
@@ -0,0 +1,134 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILIMF_WRITE_H
37
38#define MAILIMF_WRITE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <stdio.h>
45#include <libetpan/mailimf_types.h>
46
47/*
48 mailimf_string_write writes a string to a given stream
49
50 @param f is the stream
51 @param col (* col) is the column number where we will start to
52 write the text, the ending column will be stored in (* col)
53 @param str is the string to write
54*/
55
56int mailimf_string_write(FILE * f, int * col,
57 const char * str, size_t length);
58
59
60/*
61 mailimf_fields_write writes the fields to a given stream
62
63 @param f is the stream
64 @param col (* col) is the column number where we will start to
65 write the text, the ending column will be stored in (* col)
66 @param fields is the fields to write
67*/
68
69int mailimf_fields_write(FILE * f, int * col,
70 struct mailimf_fields * fields);
71
72
73/*
74 mailimf_envelope_fields_write writes only some fields to a given stream
75
76 @param f is the stream
77 @param col (* col) is the column number where we will start to
78 write the text, the ending column will be stored in (* col)
79 @param fields is the fields to write
80*/
81
82int mailimf_envelope_fields_write(FILE * f, int * col,
83 struct mailimf_fields * fields);
84
85
86/*
87 mailimf_field_write writes a field to a given stream
88
89 @param f is the stream
90 @param col (* col) is the column number where we will start to
91 write the text, the ending column will be stored in (* col)
92 @param field is the field to write
93*/
94
95int mailimf_field_write(FILE * f, int * col,
96 struct mailimf_field * field);
97
98/*
99 mailimf_quoted_string_write writes a string that is quoted
100 to a given stream
101
102 @param f is the stream
103 @param col (* col) is the column number where we will start to
104 write the text, the ending column will be stored in (* col)
105 @param string is the string to quote and write
106*/
107
108int mailimf_quoted_string_write(FILE * f, int * col,
109 const char * string, size_t len);
110
111int mailimf_address_list_write(FILE * f, int * col,
112 struct mailimf_address_list * addr_list);
113
114int mailimf_mailbox_list_write(FILE * f, int * col,
115 struct mailimf_mailbox_list * mb_list);
116
117/*
118 mailimf_header_string_write writes a header value and fold the header
119 if needed.
120
121 @param f is the stream
122 @param col (* col) is the column number where we will start to
123 write the text, the ending column will be stored in (* col)
124 @param str is the string to write
125*/
126
127int mailimf_header_string_write(FILE * f, int * col,
128 const char * str, size_t length);
129
130#ifdef __cplusplus
131}
132#endif
133
134#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailmbox.h b/kmicromail/libetpan/include/libetpan/mailmbox.h
new file mode 100644
index 0000000..8be086c
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailmbox.h
@@ -0,0 +1,140 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMBOX_H
37
38#define MAILMBOX_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailmbox_types.h>
45
46int
47mailmbox_append_message_list(struct mailmbox_folder * folder,
48 carray * append_tab);
49
50int
51mailmbox_append_message(struct mailmbox_folder * folder,
52 const char * data, size_t len);
53
54int mailmbox_fetch_msg(struct mailmbox_folder * folder,
55 uint32_t num, char ** result,
56 size_t * result_len);
57
58int mailmbox_fetch_msg_headers(struct mailmbox_folder * folder,
59 uint32_t num, char ** result,
60 size_t * result_len);
61
62void mailmbox_fetch_result_free(char * msg);
63
64int mailmbox_copy_msg_list(struct mailmbox_folder * dest_folder,
65 struct mailmbox_folder * src_folder,
66 carray * tab);
67
68int mailmbox_copy_msg(struct mailmbox_folder * dest_folder,
69 struct mailmbox_folder * src_folder,
70 uint32_t uid);
71
72int mailmbox_expunge(struct mailmbox_folder * folder);
73
74int mailmbox_delete_msg(struct mailmbox_folder * folder, uint32_t uid);
75
76int mailmbox_init(const char * filename,
77 int force_readonly,
78 int force_no_uid,
79 uint32_t default_written_uid,
80 struct mailmbox_folder ** result_folder);
81
82void mailmbox_done(struct mailmbox_folder * folder);
83
84/* low-level access primitives */
85
86int mailmbox_write_lock(struct mailmbox_folder * folder);
87
88int mailmbox_write_unlock(struct mailmbox_folder * folder);
89
90int mailmbox_read_lock(struct mailmbox_folder * folder);
91
92int mailmbox_read_unlock(struct mailmbox_folder * folder);
93
94
95/* memory map */
96
97int mailmbox_map(struct mailmbox_folder * folder);
98
99void mailmbox_unmap(struct mailmbox_folder * folder);
100
101void mailmbox_sync(struct mailmbox_folder * folder);
102
103
104/* open & close file */
105
106int mailmbox_open(struct mailmbox_folder * folder);
107
108void mailmbox_close(struct mailmbox_folder * folder);
109
110
111/* validate cache */
112
113int mailmbox_validate_write_lock(struct mailmbox_folder * folder);
114
115int mailmbox_validate_read_lock(struct mailmbox_folder * folder);
116
117
118/* fetch message */
119
120int mailmbox_fetch_msg_no_lock(struct mailmbox_folder * folder,
121 uint32_t num, char ** result,
122 size_t * result_len);
123
124int mailmbox_fetch_msg_headers_no_lock(struct mailmbox_folder * folder,
125 uint32_t num, char ** result,
126 size_t * result_len);
127
128/* append message */
129
130int
131mailmbox_append_message_list_no_lock(struct mailmbox_folder * folder,
132 carray * append_tab);
133
134int mailmbox_expunge_no_lock(struct mailmbox_folder * folder);
135
136#ifdef __cplusplus
137}
138#endif
139
140#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailmbox_types.h b/kmicromail/libetpan/include/libetpan/mailmbox_types.h
new file mode 100644
index 0000000..dd6758c
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailmbox_types.h
@@ -0,0 +1,142 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMBOX_TYPES_H
37
38#define MAILMBOX_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <sys/types.h>
45
46#include <libetpan/libetpan-config.h>
47
48#include <libetpan/mailimf.h>
49#include <libetpan/carray.h>
50#include <libetpan/chash.h>
51
52enum {
53 MAILMBOX_NO_ERROR = 0,
54 MAILMBOX_ERROR_PARSE,
55 MAILMBOX_ERROR_INVAL,
56 MAILMBOX_ERROR_FILE_NOT_FOUND,
57 MAILMBOX_ERROR_MEMORY,
58 MAILMBOX_ERROR_TEMPORARY_FILE,
59 MAILMBOX_ERROR_FILE,
60 MAILMBOX_ERROR_MSG_NOT_FOUND,
61 MAILMBOX_ERROR_READONLY,
62};
63
64
65struct mailmbox_folder {
66 char mb_filename[PATH_MAX];
67
68 time_t mb_mtime;
69
70 int mb_fd;
71 int mb_read_only;
72 int mb_no_uid;
73
74 int mb_changed;
75 unsigned int mb_deleted_count;
76
77 char * mb_mapping;
78 size_t mb_mapping_size;
79
80 uint32_t mb_written_uid;
81 uint32_t mb_max_uid;
82
83 chash * mb_hash;
84 carray * mb_tab;
85};
86
87struct mailmbox_folder * mailmbox_folder_new(const char * mb_filename);
88void mailmbox_folder_free(struct mailmbox_folder * folder);
89
90
91struct mailmbox_msg_info {
92 unsigned int msg_index;
93 uint32_t msg_uid;
94 int msg_written_uid;
95 int msg_deleted;
96
97 size_t msg_start;
98 size_t msg_start_len;
99
100 size_t msg_headers;
101 size_t msg_headers_len;
102
103 size_t msg_body;
104 size_t msg_body_len;
105
106 size_t msg_size;
107
108 size_t msg_padding;
109};
110
111
112int mailmbox_msg_info_update(struct mailmbox_folder * folder,
113 size_t msg_start, size_t msg_start_len,
114 size_t msg_headers, size_t msg_headers_len,
115 size_t msg_body, size_t msg_body_len,
116 size_t msg_size, size_t msg_padding,
117 uint32_t msg_uid);
118
119struct mailmbox_msg_info *
120mailmbox_msg_info_new(size_t msg_start, size_t msg_start_len,
121 size_t msg_headers, size_t msg_headers_len,
122 size_t msg_body, size_t msg_body_len,
123 size_t msg_size, size_t msg_padding,
124 uint32_t msg_uid);
125
126void mailmbox_msg_info_free(struct mailmbox_msg_info * info);
127
128struct mailmbox_append_info {
129 const char * ai_message;
130 size_t ai_size;
131};
132
133struct mailmbox_append_info *
134mailmbox_append_info_new(const char * ai_message, size_t ai_size);
135
136void mailmbox_append_info_free(struct mailmbox_append_info * info);
137
138#ifdef __cplusplus
139}
140#endif
141
142#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailmessage.h b/kmicromail/libetpan/include/libetpan/mailmessage.h
new file mode 100644
index 0000000..df9b790
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailmessage.h
@@ -0,0 +1,379 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include <libetpan/mailmessage_types.h>
37
38#ifndef MAILMESSAGE_H
39
40#define MAILMESSAGE_H
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 mailmessage_new
48
49 This function will initializes a new empty message.
50
51 @return a new empty message will be returned.
52*/
53
54mailmessage * mailmessage_new(void);
55
56/*
57 mailmessage_free
58
59 This function will release the memory used by this message.
60*/
61
62void mailmessage_free(mailmessage * info);
63
64/*
65 mailmessage_init
66
67 This function will initializes a mailmessage structure
68 with a message from a given session.
69
70 @param msg_info This is the message to initialize.
71
72 @param session This is the source session of the message. It
73 can be NULL if the message does not get the information
74 through the session.
75
76 @param driver This is the driver to use for the message.
77
78 @param index This is the message number in the session. 0 can
79 be given if the message is not attached to a session.
80
81 @param size is an optional parameter, 0 can be given.
82 This is informational. This is the size of message content.
83
84 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
85 on error
86*/
87
88int mailmessage_init(mailmessage * msg_info,
89 mailsession * session,
90 mailmessage_driver * driver,
91 uint32_t index, size_t size);
92
93/*
94 mailmessage_flush
95
96 This function will release all the temporary resources that are not
97 necessary to use the mailmessage structure from memory. These
98 resources are for example cached information, such as the MIME
99 structure.
100
101 @param info is the message to clean.
102
103 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
104 on error. We can assume that MAIL_NO_ERROR is always returned.
105*/
106
107int mailmessage_flush(mailmessage * info);
108
109/*
110 mailmessage_check
111
112 This function will notify the new value of the flags to the session,
113 it must be called before mailsession_check_folder() in case the flags have
114 been changed.
115
116 @param info is the message to checkpoint.
117
118 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
119 on error. We can assume that MAIL_NO_ERROR is always returned.
120*/
121
122int mailmessage_check(mailmessage * info);
123
124/*
125 mailmessage_fetch_result_free
126
127 This function releases the memory used by a message returned
128 by any of the fetch function that returns a (char *).
129
130 @param msg_info is the message which the given buffer is from.
131
132 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
133 on error. We can assume that MAIL_NO_ERROR is always returned.
134*/
135
136int mailmessage_fetch_result_free(mailmessage * msg_info,
137 char * msg);
138
139/*
140 mailmessage_fetch
141
142 This function returns the content of the message (headers and text).
143
144 @param msg_info is the message from which we want to fetch information.
145
146 @param result The content of the message is returned in (* result)
147
148 @param result_len The length of the returned string is stored
149 in (* result_len).
150
151 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
152 on error.
153*/
154
155int mailmessage_fetch(mailmessage * msg_info,
156 char ** result,
157 size_t * result_len);
158
159/*
160 mailmessage_fetch_header
161
162 This function returns the header of the message as a string.
163
164 @param msg_info is the message from which we want to fetch information.
165
166 @param result The header of the message is returned in (* result)
167
168 @param result_len The length of the returned string is stored
169 in (* result_len).
170
171 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
172 on error.
173*/
174
175int mailmessage_fetch_header(mailmessage * msg_info,
176 char ** result,
177 size_t * result_len);
178
179/*
180 mailmessage_fetch_body
181
182 This function returns the content of the message (without headers).
183
184 @param msg_info is the message from which we want to fetch information.
185 @param result The message text (without headers) is returned
186 in (* result)
187 @param result_len The length of the returned string is stored
188 in (* result_len).
189
190 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
191 on error.
192*/
193
194int mailmessage_fetch_body(mailmessage * msg_info,
195 char ** result, size_t * result_len);
196
197/*
198 mailmessage_fetch_size
199
200 This function returns the size of the message content.
201
202 @param msg_info is the message from which we want to fetch information.
203
204 @param result The length of the message content is stored in (* result).
205
206 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
207 on error.
208*/
209
210int mailmessage_fetch_size(mailmessage * msg_info,
211 size_t * result);
212
213/*
214 mailmessage_get_bodystructure
215
216 This functions returns the MIME structure of the message.
217 The returned information MUST not be freed by hand. It is freed by
218 mailmessage_flush() or mailmessage_free().
219
220 @param msg_info is the message from which we want to fetch information.
221
222 @param result The MIME structure is stored in (* result).
223
224 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
225 on error.
226*/
227
228int mailmessage_get_bodystructure(mailmessage * msg_info,
229 struct mailmime ** result);
230
231/*
232 mailmessage_fetch_section
233
234 This function returns the content of a MIME part.
235
236 @param msg_info is the message from which we want to fetch information.
237
238 @param mime is the MIME part identifier.
239
240 @param result The content is returned in (* result)
241
242 @param result_len The length of the returned string is stored
243 in (* result_len).
244
245 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
246 on error.
247 */
248
249int mailmessage_fetch_section(mailmessage * msg_info,
250 struct mailmime * mime,
251 char ** result, size_t * result_len);
252
253/*
254 mailmessage_fetch_section_header
255
256 This function returns the header of the message contained
257 in the given MIME part.
258
259 @param msg_info is the message from which we want to fetch information.
260
261 @param mime is the MIME part identifier.
262
263 @param result The header is returned in (* result)
264
265 @param result_len The length of the returned string is stored
266 in (* result_len).
267
268 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
269 on error.
270*/
271
272int mailmessage_fetch_section_header(mailmessage * msg_info,
273 struct mailmime * mime,
274 char ** result,
275 size_t * result_len);
276
277/*
278 mailmessage_fetch_section_mime
279
280 This function returns the MIME header of the given MIME part.
281
282 @param msg_info is the message from which we want to fetch information.
283
284 @param mime is the MIME part identifier.
285
286 @param result The MIME header is returned in (* result)
287
288 @param result_len The length of the returned string is stored
289 in (* result_len).
290
291 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
292 on error.
293*/
294
295int mailmessage_fetch_section_mime(mailmessage * msg_info,
296 struct mailmime * mime,
297 char ** result,
298 size_t * result_len);
299
300/*
301 mailmessage_fetch_section_body
302
303 This function returns the text part of the message contained
304 in the given MIME part.
305
306 @param msg_info is the message from which we want to fetch information.
307
308 @param mime is the MIME part identifier.
309
310 @param result The message text is returned in (* result)
311
312 @param result_len The length of the returned string is stored
313 in (* result_len).
314
315 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
316 on error.
317 */
318
319int mailmessage_fetch_section_body(mailmessage * msg_info,
320 struct mailmime * mime,
321 char ** result,
322 size_t * result_len);
323
324/*
325 mailmessage_fetch_envelope
326
327 This function returns a list of parsed fields of the message,
328 chosen by the driver.
329 The returned structure must be freed with mailimf_fields_free().
330
331 @param msg_info is the message from which we want to fetch information.
332
333 @param result The headers list is returned in (* result)
334
335 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
336 on error.
337 */
338
339int mailmessage_fetch_envelope(mailmessage * msg_info,
340 struct mailimf_fields ** result);
341
342
343/*
344 mailmessage_get_flags
345
346 This function returns the flags related to the message.
347 The returned information MUST not be freed by hand. It is freed by
348 mailmessage_free().
349
350 @param msg_info is the message from which we want to fetch information.
351
352 @param result The flags are stored in (* result).
353
354 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
355 on error.
356*/
357
358int mailmessage_get_flags(mailmessage * msg_info,
359 struct mail_flags ** result);
360
361/*
362 mailmessage_resolve_single_fields
363
364 This function will use the fields information to fill the single_fields
365 structure in the mailmessage structure.
366
367 @param msg_info This is the msg_info to process.
368
369 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
370 on error.
371*/
372
373void mailmessage_resolve_single_fields(mailmessage * msg_info);
374
375#ifdef __cplusplus
376}
377#endif
378
379#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailmessage_types.h b/kmicromail/libetpan/include/libetpan/mailmessage_types.h
new file mode 100644
index 0000000..655ed2c
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailmessage_types.h
@@ -0,0 +1,50 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMESSAGE_TYPES_H
37
38#define MAILMESSAGE_TYPES_H
39
40#include <libetpan/maildriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46#ifdef __cplusplus
47}
48#endif
49
50#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailmh.h b/kmicromail/libetpan/include/libetpan/mailmh.h
new file mode 100644
index 0000000..40432cb
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailmh.h
@@ -0,0 +1,143 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMH_H
37
38#define MAILMH_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <sys/types.h>
45#include <inttypes.h>
46#include <libetpan/carray.h>
47#include <libetpan/cinthash.h>
48#include <libetpan/chash.h>
49
50enum {
51 MAILMH_NO_ERROR = 0,
52 MAILMH_ERROR_FOLDER,
53 MAILMH_ERROR_MEMORY,
54 MAILMH_ERROR_FILE,
55 MAILMH_ERROR_COULD_NOT_ALLOC_MSG,
56 MAILMH_ERROR_RENAME,
57 MAILMH_ERROR_MSG_NOT_FOUND,
58};
59
60struct mailmh {
61 struct mailmh_folder * mh_main;
62};
63
64struct mailmh_msg_info {
65 unsigned int msg_array_index;
66 uint32_t msg_index;
67 size_t msg_size;
68 time_t msg_mtime;
69};
70
71struct mailmh_folder {
72 char * fl_filename;
73 unsigned int fl_array_index;
74
75 char * fl_name;
76 time_t fl_mtime;
77 struct mailmh_folder * fl_parent;
78 uint32_t fl_max_index;
79
80 carray * fl_msgs_tab;
81#if 0
82 cinthash_t * fl_msgs_hash;
83#endif
84 chash * fl_msgs_hash;
85
86 carray * fl_subfolders_tab;
87 chash * fl_subfolders_hash;
88};
89
90struct mailmh * mailmh_new(const char * foldername);
91void mailmh_free(struct mailmh * f);
92
93struct mailmh_msg_info *
94mailmh_msg_info_new(uint32_t index, size_t size, time_t mtime);
95void mailmh_msg_info_free(struct mailmh_msg_info * msg_info);
96
97struct mailmh_folder * mailmh_folder_new(struct mailmh_folder * parent,
98 const char * name);
99void mailmh_folder_free(struct mailmh_folder * folder);
100
101int mailmh_folder_add_subfolder(struct mailmh_folder * parent,
102 const char * name);
103
104struct mailmh_folder * mailmh_folder_find(struct mailmh_folder * root,
105 const char * filename);
106
107int mailmh_folder_remove_subfolder(struct mailmh_folder * folder);
108
109int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder,
110 struct mailmh_folder * dst_folder,
111 const char * new_name);
112
113int mailmh_folder_get_message_filename(struct mailmh_folder * folder,
114 uint32_t index, char ** result);
115
116int mailmh_folder_get_message_fd(struct mailmh_folder * folder,
117 uint32_t index, int flags, int * result);
118
119int mailmh_folder_get_message_size(struct mailmh_folder * folder,
120 uint32_t index, size_t * result);
121
122int mailmh_folder_add_message(struct mailmh_folder * folder,
123 const char * message, size_t size);
124
125int mailmh_folder_add_message_file(struct mailmh_folder * folder,
126 int fd);
127
128int mailmh_folder_remove_message(struct mailmh_folder * folder,
129 uint32_t index);
130
131int mailmh_folder_move_message(struct mailmh_folder * dest_folder,
132 struct mailmh_folder * src_folder,
133 uint32_t index);
134
135int mailmh_folder_update(struct mailmh_folder * folder);
136
137unsigned int mailmh_folder_get_message_number(struct mailmh_folder * folder);
138
139#ifdef __cplusplus
140}
141#endif
142
143#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailmime.h b/kmicromail/libetpan/include/libetpan/mailmime.h
new file mode 100644
index 0000000..c834967
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailmime.h
@@ -0,0 +1,100 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMIME_H
37
38#define MAILMIME_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailimf.h>
45#include <libetpan/mailmime_types.h>
46#include <libetpan/mailmime_types_helper.h>
47#include <libetpan/mailmime_content.h>
48#include <libetpan/mailmime_decode.h>
49#include <libetpan/mailmime_disposition.h>
50#include <libetpan/mailmime_write.h>
51
52int mailmime_content_parse(const char * message, size_t length,
53 size_t * index,
54 struct mailmime_content ** result);
55
56int mailmime_description_parse(const char * message, size_t length,
57 size_t * index,
58 char ** result);
59
60int mailmime_encoding_parse(const char * message, size_t length,
61 size_t * index,
62 struct mailmime_mechanism ** result);
63
64int
65mailmime_field_parse(struct mailimf_optional_field * field,
66 struct mailmime_field ** result);
67
68int mailmime_id_parse(const char * message, size_t length,
69 size_t * index, char ** result);
70
71int
72mailmime_fields_parse(struct mailimf_fields *
73 fields,
74 struct mailmime_fields **
75 result);
76
77int mailmime_version_parse(const char * message, size_t length,
78 size_t * index,
79 uint32_t * result);
80
81int
82mailmime_extension_token_parse(const char * message, size_t length,
83 size_t * index, char ** result);
84
85int mailmime_parameter_parse(const char * message, size_t length,
86 size_t * index,
87 struct mailmime_parameter ** result);
88
89int mailmime_value_parse(const char * message, size_t length,
90 size_t * index, char ** result);
91
92int mailmime_language_parse(const char * message, size_t length,
93 size_t * index,
94 struct mailmime_language ** result);
95
96#ifdef __cplusplus
97}
98#endif
99
100#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailmime_content.h b/kmicromail/libetpan/include/libetpan/mailmime_content.h
new file mode 100644
index 0000000..df4b232
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailmime_content.h
@@ -0,0 +1,89 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMIME_CONTENT_H
37
38#define MAILMIME_CONTENT_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailmime_types.h>
45
46char * mailmime_content_charset_get(struct mailmime_content * content);
47
48char * mailmime_content_param_get(struct mailmime_content * content,
49 char * name);
50
51int mailmime_parse(const char * message, size_t length,
52 size_t * index, struct mailmime ** result);
53
54int mailmime_get_section(struct mailmime * mime,
55 struct mailmime_section * section,
56 struct mailmime ** result);
57
58
59char * mailmime_extract_boundary(struct mailmime_content * content_type);
60
61
62/* decode */
63
64int mailmime_base64_body_parse(const char * message, size_t length,
65 size_t * index, char ** result,
66 size_t * result_len);
67
68int mailmime_quoted_printable_body_parse(const char * message, size_t length,
69 size_t * index, char ** result,
70 size_t * result_len, int in_header);
71
72
73int mailmime_binary_body_parse(const char * message, size_t length,
74 size_t * index, char ** result,
75 size_t * result_len);
76
77int mailmime_part_parse(const char * message, size_t length,
78 size_t * index,
79 int encoding, char ** result, size_t * result_len);
80
81
82int mailmime_get_section_id(struct mailmime * mime,
83 struct mailmime_section ** result);
84
85#ifdef __cplusplus
86}
87#endif
88
89#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailmime_decode.h b/kmicromail/libetpan/include/libetpan/mailmime_decode.h
new file mode 100644
index 0000000..034db6f
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailmime_decode.h
@@ -0,0 +1,55 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMIME_DECODE_H
37
38#define MAILMIME_DECODE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailmime_types.h>
45
46int mailmime_encoded_phrase_parse(const char * default_fromcode,
47 const char * message, size_t length,
48 size_t * index, const char * tocode,
49 char ** result);
50
51#ifdef __cplusplus
52}
53#endif
54
55#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailmime_disposition.h b/kmicromail/libetpan/include/libetpan/mailmime_disposition.h
new file mode 100644
index 0000000..e3bba15
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailmime_disposition.h
@@ -0,0 +1,62 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMIME_DISPOSITION_H
37
38#define MAILMIME_DISPOSITION_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailmime_types.h>
45
46int mailmime_disposition_parse(const char * message, size_t length,
47 size_t * index,
48 struct mailmime_disposition ** result);
49
50int
51mailmime_disposition_type_parse(const char * message, size_t length,
52 size_t * index,
53 struct mailmime_disposition_type ** result);
54
55int mailmime_disposition_guess_type(const char * message, size_t length,
56 size_t index);
57
58#ifdef __cplusplus
59}
60#endif
61
62#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailmime_types.h b/kmicromail/libetpan/include/libetpan/mailmime_types.h
new file mode 100644
index 0000000..3bb3b10
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailmime_types.h
@@ -0,0 +1,440 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMIME_TYPES_H
37
38#define MAILMIME_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45#include <libetpan/mailimf.h>
46#include <libetpan/clist.h>
47
48enum {
49 MAILMIME_COMPOSITE_TYPE_ERROR,
50 MAILMIME_COMPOSITE_TYPE_MESSAGE,
51 MAILMIME_COMPOSITE_TYPE_MULTIPART,
52 MAILMIME_COMPOSITE_TYPE_EXTENSION
53};
54
55struct mailmime_composite_type {
56 int ct_type;
57 char * ct_token;
58};
59
60
61struct mailmime_content {
62 struct mailmime_type * ct_type;
63 char * ct_subtype;
64 clist * ct_parameters; /* elements are (struct mailmime_parameter *) */
65};
66
67
68enum {
69 MAILMIME_DISCRETE_TYPE_ERROR,
70 MAILMIME_DISCRETE_TYPE_TEXT,
71 MAILMIME_DISCRETE_TYPE_IMAGE,
72 MAILMIME_DISCRETE_TYPE_AUDIO,
73 MAILMIME_DISCRETE_TYPE_VIDEO,
74 MAILMIME_DISCRETE_TYPE_APPLICATION,
75 MAILMIME_DISCRETE_TYPE_EXTENSION
76};
77
78struct mailmime_discrete_type {
79 int dt_type;
80 char * dt_extension;
81};
82
83enum {
84 MAILMIME_FIELD_NONE,
85 MAILMIME_FIELD_TYPE,
86 MAILMIME_FIELD_TRANSFER_ENCODING,
87 MAILMIME_FIELD_ID,
88 MAILMIME_FIELD_DESCRIPTION,
89 MAILMIME_FIELD_VERSION,
90 MAILMIME_FIELD_DISPOSITION,
91 MAILMIME_FIELD_LANGUAGE,
92};
93
94struct mailmime_field {
95 int fld_type;
96 union {
97 struct mailmime_content * fld_content;
98 struct mailmime_mechanism * fld_encoding;
99 char * fld_id;
100 char * fld_description;
101 uint32_t fld_version;
102 struct mailmime_disposition * fld_disposition;
103 struct mailmime_language * fld_language;
104 } fld_data;
105};
106
107enum {
108 MAILMIME_MECHANISM_ERROR,
109 MAILMIME_MECHANISM_7BIT,
110 MAILMIME_MECHANISM_8BIT,
111 MAILMIME_MECHANISM_BINARY,
112 MAILMIME_MECHANISM_QUOTED_PRINTABLE,
113 MAILMIME_MECHANISM_BASE64,
114 MAILMIME_MECHANISM_TOKEN
115};
116
117struct mailmime_mechanism {
118 int enc_type;
119 char * enc_token;
120};
121
122
123struct mailmime_fields {
124 clist * fld_list; /* list of (struct mailmime_field *) */
125};
126
127
128struct mailmime_parameter {
129 char * pa_name;
130 char * pa_value;
131};
132
133enum {
134 MAILMIME_TYPE_ERROR,
135 MAILMIME_TYPE_DISCRETE_TYPE,
136 MAILMIME_TYPE_COMPOSITE_TYPE
137};
138
139struct mailmime_type {
140 int tp_type;
141 union {
142 struct mailmime_discrete_type * tp_discrete_type;
143 struct mailmime_composite_type * tp_composite_type;
144 } tp_data;
145};
146
147void mailmime_attribute_free(char * attribute);
148
149struct mailmime_composite_type *
150mailmime_composite_type_new(int ct_type, char * ct_token);
151
152void mailmime_composite_type_free(struct mailmime_composite_type * ct);
153
154struct mailmime_content *
155mailmime_content_new(struct mailmime_type * ct_type,
156 char * ct_subtype,
157 clist * ct_parameters);
158
159void mailmime_content_free(struct mailmime_content * content);
160
161void mailmime_description_free(char * description);
162
163struct mailmime_discrete_type *
164mailmime_discrete_type_new(int dt_type, char * dt_extension);
165
166void mailmime_discrete_type_free(struct mailmime_discrete_type *
167 discrete_type);
168
169void mailmime_encoding_free(struct mailmime_mechanism * encoding);
170
171void mailmime_extension_token_free(char * extension);
172
173void mailmime_id_free(char * id);
174
175struct mailmime_mechanism * mailmime_mechanism_new(int enc_type, char * enc_token);
176
177void mailmime_mechanism_free(struct mailmime_mechanism * mechanism);
178
179struct mailmime_parameter *
180mailmime_parameter_new(char * pa_name, char * pa_value);
181
182void mailmime_parameter_free(struct mailmime_parameter * parameter);
183
184void mailmime_subtype_free(char * subtype);
185
186void mailmime_token_free(char * token);
187
188struct mailmime_type *
189mailmime_type_new(int tp_type,
190 struct mailmime_discrete_type * tp_discrete_type,
191 struct mailmime_composite_type * tp_composite_type);
192
193void mailmime_type_free(struct mailmime_type * type);
194
195void mailmime_value_free(char * value);
196
197
198
199struct mailmime_language {
200 clist * lg_list; /* atom (char *) */
201};
202
203struct mailmime_language * mailmime_language_new(clist * lg_list);
204
205void mailmime_language_free(struct mailmime_language * lang);
206
207
208/*
209void mailmime_x_token_free(gchar * x_token);
210*/
211
212struct mailmime_field *
213mailmime_field_new(int fld_type,
214 struct mailmime_content * fld_content,
215 struct mailmime_mechanism * fld_encoding,
216 char * fld_id,
217 char * fld_description,
218 uint32_t fld_version,
219 struct mailmime_disposition * fld_disposition,
220 struct mailmime_language * fld_language);
221
222void mailmime_field_free(struct mailmime_field * field);
223
224struct mailmime_fields * mailmime_fields_new(clist * fld_list);
225
226void mailmime_fields_free(struct mailmime_fields * fields);
227
228
229struct mailmime_multipart_body {
230 clist * bd_list;
231};
232
233struct mailmime_multipart_body *
234mailmime_multipart_body_new(clist * bd_list);
235
236void mailmime_multipart_body_free(struct mailmime_multipart_body * mp_body);
237
238
239enum {
240 MAILMIME_DATA_TEXT,
241 MAILMIME_DATA_FILE,
242};
243
244struct mailmime_data {
245 int dt_type;
246 int dt_encoding;
247 int dt_encoded;
248 union {
249 struct {
250 const char * dt_data;
251 size_t dt_length;
252 } dt_text;
253 char * dt_filename;
254 } dt_data;
255};
256
257struct mailmime_data * mailmime_data_new(int dt_type, int dt_encoding,
258 int dt_encoded, const char * dt_data, size_t dt_length,
259 char * dt_filename);
260
261void mailmime_data_free(struct mailmime_data * mime_data);
262
263
264enum {
265 MAILMIME_NONE,
266 MAILMIME_SINGLE,
267 MAILMIME_MULTIPLE,
268 MAILMIME_MESSAGE,
269};
270
271struct mailmime {
272 /* parent information */
273 int mm_parent_type;
274 struct mailmime * mm_parent;
275 clistiter * mm_multipart_pos;
276
277 int mm_type;
278 const char * mm_mime_start;
279 size_t mm_length;
280
281 struct mailmime_fields * mm_mime_fields;
282 struct mailmime_content * mm_content_type;
283
284 struct mailmime_data * mm_body;
285 union {
286 /* single part */
287 struct mailmime_data * mm_single; /* XXX - was body */
288
289 /* multi-part */
290 struct {
291 struct mailmime_data * mm_preamble;
292 struct mailmime_data * mm_epilogue;
293 clist * mm_mp_list;
294 } mm_multipart;
295
296 /* message */
297 struct {
298 struct mailimf_fields * mm_fields;
299 struct mailmime * mm_msg_mime;
300 } mm_message;
301
302 } mm_data;
303};
304
305struct mailmime * mailmime_new(int mm_type,
306 const char * mm_mime_start, size_t mm_length,
307 struct mailmime_fields * mm_mime_fields,
308 struct mailmime_content * mm_content_type,
309 struct mailmime_data * mm_body,
310 struct mailmime_data * mm_preamble,
311 struct mailmime_data * mm_epilogue,
312 clist * mm_mp_list,
313 struct mailimf_fields * mm_fields,
314 struct mailmime * mm_msg_mime);
315
316void mailmime_free(struct mailmime * mime);
317
318struct mailmime_encoded_word {
319 char * wd_charset;
320 char * wd_text;
321};
322
323struct mailmime_encoded_word *
324mailmime_encoded_word_new(char * wd_charset, char * wd_text);
325
326void mailmime_encoded_word_free(struct mailmime_encoded_word * ew);
327
328void mailmime_charset_free(char * charset);
329
330void mailmime_encoded_text_free(char * text);
331
332
333struct mailmime_disposition {
334 struct mailmime_disposition_type * dsp_type;
335 clist * dsp_parms; /* struct mailmime_disposition_parm */
336};
337
338
339enum {
340 MAILMIME_DISPOSITION_TYPE_ERROR,
341 MAILMIME_DISPOSITION_TYPE_INLINE,
342 MAILMIME_DISPOSITION_TYPE_ATTACHMENT,
343 MAILMIME_DISPOSITION_TYPE_EXTENSION
344};
345
346struct mailmime_disposition_type {
347 int dsp_type;
348 char * dsp_extension;
349};
350
351
352enum {
353 MAILMIME_DISPOSITION_PARM_FILENAME,
354 MAILMIME_DISPOSITION_PARM_CREATION_DATE,
355 MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE,
356 MAILMIME_DISPOSITION_PARM_READ_DATE,
357 MAILMIME_DISPOSITION_PARM_SIZE,
358 MAILMIME_DISPOSITION_PARM_PARAMETER
359};
360
361struct mailmime_disposition_parm {
362 int pa_type;
363 union {
364 char * pa_filename;
365 char * pa_creation_date;
366 char * pa_modification_date;
367 char * pa_read_date;
368 size_t pa_size;
369 struct mailmime_parameter * pa_parameter;
370 } pa_data;
371};
372
373struct mailmime_disposition *
374mailmime_disposition_new(struct mailmime_disposition_type * dsp_type,
375 clist * dsp_parms);
376
377void mailmime_disposition_free(struct mailmime_disposition * dsp);
378
379struct mailmime_disposition_type *
380mailmime_disposition_type_new(int dt_type, char * dt_extension);
381
382void mailmime_disposition_type_free(struct mailmime_disposition_type * dsp_type);
383
384struct mailmime_disposition_parm *
385mailmime_disposition_parm_new(int pa_type,
386 char * pa_filename,
387 char * pa_creation_date,
388 char * pa_modification_date,
389 char * pa_read_date,
390 size_t pa_size,
391 struct mailmime_parameter * pa_parameter);
392
393void mailmime_disposition_parm_free(struct mailmime_disposition_parm *
394 dsp_parm);
395
396void mailmime_filename_parm_free(char * filename);
397
398void mailmime_creation_date_parm_free(char * date);
399
400void mailmime_modification_date_parm_free(char * date);
401
402void mailmime_read_date_parm_free(char * date);
403
404void mailmime_quoted_date_time_free(char * date);
405
406struct mailmime_section {
407 clist * sec_list; /* list of (uint32 *) */
408};
409
410struct mailmime_section * mailmime_section_new(clist * list);
411
412void mailmime_section_free(struct mailmime_section * section);
413
414
415void mailmime_decoded_part_free(char * part);
416
417struct mailmime_single_fields {
418 struct mailmime_content * fld_content;
419 char * fld_content_charset;
420 char * fld_content_boundary;
421 char * fld_content_name;
422 struct mailmime_mechanism * fld_encoding;
423 char * fld_id;
424 char * fld_description;
425 uint32_t fld_version;
426 struct mailmime_disposition * fld_disposition;
427 char * fld_disposition_filename;
428 char * fld_disposition_creation_date;
429 char * fld_disposition_modification_date;
430 char * fld_disposition_read_date;
431 size_t fld_disposition_size;
432 struct mailmime_language * fld_language;
433};
434
435#ifdef __cplusplus
436}
437#endif
438
439#endif
440
diff --git a/kmicromail/libetpan/include/libetpan/mailmime_types_helper.h b/kmicromail/libetpan/include/libetpan/mailmime_types_helper.h
new file mode 100644
index 0000000..608acca
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailmime_types_helper.h
@@ -0,0 +1,165 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMIME_TYPES_HELPER_H
37
38#define MAILMIME_TYPES_HELPER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailmime_types.h>
45
46int mailmime_transfer_encoding_get(struct mailmime_fields * fields);
47
48struct mailmime_disposition *
49mailmime_disposition_new_filename(int type, char * filename);
50
51struct mailmime_fields * mailmime_fields_new_empty(void);
52
53int mailmime_fields_add(struct mailmime_fields * fields,
54 struct mailmime_field * field);
55
56struct mailmime_fields *
57mailmime_fields_new_with_data(struct mailmime_mechanism * encoding,
58 char * id,
59 char * description,
60 struct mailmime_disposition * disposition,
61 struct mailmime_language * language);
62
63struct mailmime_fields *
64mailmime_fields_new_with_version(struct mailmime_mechanism * encoding,
65 char * id,
66 char * description,
67 struct mailmime_disposition * disposition,
68 struct mailmime_language * language);
69
70struct mailmime_content * mailmime_get_content_message(void);
71struct mailmime_content * mailmime_get_content_text(void);
72/* struct mailmime_content * mailmime_get_content(char * mime_type); */
73
74#define mailmime_get_content mailmime_content_new_with_str
75
76struct mailmime_data *
77mailmime_data_new_data(int encoding, int encoded,
78 const char * data, size_t length);
79
80struct mailmime_data *
81mailmime_data_new_file(int encoding, int encoded,
82 char * filename);
83
84#if 0
85struct mailmime *
86mailmime_new_message_file(char * filename);
87
88struct mailmime *
89mailmime_new_message_text(char * data_str, size_t length);
90#endif
91
92struct mailmime *
93mailmime_new_message_data(struct mailmime * msg_mime);
94
95struct mailmime *
96mailmime_new_empty(struct mailmime_content * content,
97 struct mailmime_fields * mime_fields);
98
99int
100mailmime_new_with_content(const char * content_type,
101 struct mailmime_fields * mime_fields,
102 struct mailmime ** result);
103
104int mailmime_set_preamble_file(struct mailmime * build_info,
105 char * filename);
106
107int mailmime_set_epilogue_file(struct mailmime * build_info,
108 char * filename);
109
110int mailmime_set_preamble_text(struct mailmime * build_info,
111 char * data_str, size_t length);
112
113int mailmime_set_epilogue_text(struct mailmime * build_info,
114 char * data_str, size_t length);
115
116int mailmime_set_body_file(struct mailmime * build_info,
117 char * filename);
118
119int mailmime_set_body_text(struct mailmime * build_info,
120 char * data_str, size_t length);
121
122int mailmime_add_part(struct mailmime * build_info,
123 struct mailmime * part);
124
125void mailmime_remove_part(struct mailmime * mime);
126
127void mailmime_set_imf_fields(struct mailmime * build_info,
128 struct mailimf_fields * fields);
129
130
131struct mailmime_disposition *
132mailmime_disposition_new_with_data(int type,
133 char * filename, char * creation_date, char * modification_date,
134 char * read_date, size_t size);
135
136void mailmime_single_fields_init(struct mailmime_single_fields * single_fields,
137 struct mailmime_fields * fld_fields,
138 struct mailmime_content * fld_content);
139
140struct mailmime_single_fields *
141mailmime_single_fields_new(struct mailmime_fields * fld_fields,
142 struct mailmime_content * fld_content);
143
144void mailmime_single_fields_free(struct mailmime_single_fields *
145 single_fields);
146
147int mailmime_smart_add_part(struct mailmime * mime,
148 struct mailmime * mime_sub);
149
150int mailmime_smart_remove_part(struct mailmime * mime);
151
152struct mailmime_content * mailmime_content_new_with_str(const char * str);
153
154struct mailmime_fields * mailmime_fields_new_encoding(int type);
155
156struct mailmime * mailmime_multiple_new(const char * type);
157
158struct mailmime_fields * mailmime_fields_new_filename(int dsp_type,
159 char * filename, int encoding_type);
160
161#ifdef __cplusplus
162}
163#endif
164
165#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailmime_write.h b/kmicromail/libetpan/include/libetpan/mailmime_write.h
new file mode 100644
index 0000000..96f8777
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailmime_write.h
@@ -0,0 +1,73 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMIME_WRITE_H
37
38#define MAILMIME_WRITE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailmime_types.h>
45#include <stdio.h>
46
47int mailmime_fields_write(FILE * f, int * col,
48 struct mailmime_fields * fields);
49
50int mailmime_content_write(FILE * f, int * col,
51 struct mailmime_content * content);
52
53int mailmime_content_type_write(FILE * f, int * col,
54 struct mailmime_content * content);
55
56int mailmime_write(FILE * f, int * col,
57 struct mailmime * build_info);
58
59int mailmime_quoted_printable_write(FILE * f, int * col, int istext,
60 const char * text, size_t size);
61
62int mailmime_base64_write(FILE * f, int * col,
63 const char * text, size_t size);
64
65int mailmime_data_write(FILE * f, int * col,
66 struct mailmime_data * data,
67 int istext);
68
69#ifdef __cplusplus
70}
71#endif
72
73#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailpop3.h b/kmicromail/libetpan/include/libetpan/mailpop3.h
new file mode 100644
index 0000000..b8552ab
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailpop3.h
@@ -0,0 +1,100 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILPOP3_H
37
38#define MAILPOP3_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailpop3_types.h>
45
46#include <libetpan/mailpop3_helper.h>
47
48#include <libetpan/mailpop3_socket.h>
49#include <libetpan/mailpop3_ssl.h>
50
51#define POP3_STRING_SIZE 513
52
53mailpop3 * mailpop3_new(size_t pop3_progr_rate,
54 progress_function * pop3_progr_fun);
55
56void mailpop3_free(mailpop3 * f);
57
58int mailpop3_connect(mailpop3 * f, mailstream * s);
59
60int mailpop3_quit(mailpop3 * f);
61
62
63int mailpop3_apop(mailpop3 * f, const char * user, const char * password);
64
65int mailpop3_user(mailpop3 * f, const char * user);
66
67int mailpop3_pass(mailpop3 * f, const char * password);
68
69void mailpop3_list(mailpop3 * f, carray ** result);
70
71int mailpop3_retr(mailpop3 * f, uint32_t index, char ** result,
72 size_t * result_len);
73
74int mailpop3_top(mailpop3 * f, uint32_t index, uint32_t count,
75 char ** result, size_t * result_len);
76
77int mailpop3_dele(mailpop3 * f, uint32_t index);
78
79int mailpop3_noop(mailpop3 * f);
80
81int mailpop3_rset(mailpop3 * f);
82
83void mailpop3_top_free(char * str);
84
85void mailpop3_retr_free(char * str);
86
87int mailpop3_get_msg_info(mailpop3 * f, uint32_t index,
88 struct mailpop3_msg_info ** result);
89
90int mailpop3_capa(mailpop3 * f, clist ** result);
91
92void mailpop3_capa_resp_free(clist * capa_list);
93
94int mailpop3_stls(mailpop3 * f);
95
96#ifdef __cplusplus
97}
98#endif
99
100#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailpop3_helper.h b/kmicromail/libetpan/include/libetpan/mailpop3_helper.h
new file mode 100644
index 0000000..7337ad8
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailpop3_helper.h
@@ -0,0 +1,64 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILPOP3_HELPER_H
37
38#define MAILPOP3_HELPER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mailpop3.h"
45
46int mailpop3_login_apop(mailpop3 * f,
47 char * user,
48 char * password);
49
50int mailpop3_login(mailpop3 * f,
51 char * user,
52 char * password);
53
54int mailpop3_header(mailpop3 * f, uint32_t index, char ** result,
55 size_t * result_len);
56
57void mailpop3_header_free(char * str);
58
59#ifdef __cplusplus
60}
61#endif
62
63#endif
64
diff --git a/kmicromail/libetpan/include/libetpan/mailpop3_socket.h b/kmicromail/libetpan/include/libetpan/mailpop3_socket.h
new file mode 100644
index 0000000..06f16f5
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailpop3_socket.h
@@ -0,0 +1,54 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILPOP3_SOCKET_H
37
38#define MAILPOP3_SOCKET_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45
46#include <libetpan/mailpop3_types.h>
47
48int mailpop3_socket_connect(mailpop3 * f, const char * server, uint16_t port);
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailpop3_ssl.h b/kmicromail/libetpan/include/libetpan/mailpop3_ssl.h
new file mode 100644
index 0000000..926001c
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailpop3_ssl.h
@@ -0,0 +1,54 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILPOP3_SSL_H
37
38#define MAILPOP3_SSL_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45
46#include <libetpan/mailpop3_types.h>
47
48int mailpop3_ssl_connect(mailpop3 * f, const char * server, uint16_t port);
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailpop3_types.h b/kmicromail/libetpan/include/libetpan/mailpop3_types.h
new file mode 100644
index 0000000..20500f6
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailpop3_types.h
@@ -0,0 +1,107 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILPOP3_TYPES_H
37
38#define MAILPOP3_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailstream.h>
45#include <libetpan/mmapstring.h>
46#include <libetpan/carray.h>
47#include <libetpan/clist.h>
48
49#include <inttypes.h>
50
51enum {
52 MAILPOP3_NO_ERROR = 0,
53 MAILPOP3_ERROR_BAD_STATE,
54 MAILPOP3_ERROR_UNAUTHORIZED,
55 MAILPOP3_ERROR_STREAM,
56 MAILPOP3_ERROR_DENIED,
57 MAILPOP3_ERROR_BAD_USER,
58 MAILPOP3_ERROR_BAD_PASSWORD,
59 MAILPOP3_ERROR_CANT_LIST,
60 MAILPOP3_ERROR_NO_SUCH_MESSAGE,
61 MAILPOP3_ERROR_MEMORY,
62 MAILPOP3_ERROR_CONNECTION_REFUSED,
63 MAILPOP3_ERROR_APOP_NOT_SUPPORTED,
64 MAILPOP3_ERROR_CAPA_NOT_SUPPORTED,
65 MAILPOP3_ERROR_STLS_NOT_SUPPORTED,
66};
67
68struct mailpop3
69{
70 char * pop3_response; /* response message */
71 char * pop3_timestamp; /* connection timestamp */
72
73 /* internals */
74 mailstream * pop3_stream;
75 size_t pop3_progr_rate;
76 progress_function * pop3_progr_fun;
77
78 MMAPString * pop3_stream_buffer; /* buffer for lines reading */
79 MMAPString * pop3_response_buffer; /* buffer for responses */
80
81 carray * pop3_msg_tab; /* list of pop3_msg_info structures */
82 int pop3_state; /* state */
83
84 unsigned int pop3_deleted_count;
85};
86
87typedef struct mailpop3 mailpop3;
88
89struct mailpop3_msg_info
90{
91 unsigned int msg_index;
92 uint32_t msg_size;
93 char * msg_uidl;
94 int msg_deleted;
95};
96
97
98struct mailpop3_capa {
99 char * cap_name;
100 clist * cap_param; /* (char *) */
101};
102
103#ifdef __cplusplus
104}
105#endif
106
107#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailsmtp.h b/kmicromail/libetpan/include/libetpan/mailsmtp.h
new file mode 100644
index 0000000..548a5b7
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailsmtp.h
@@ -0,0 +1,94 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSMTP_H
37
38#define MAILSMTP_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailsmtp_types.h>
45#include <libetpan/mailsmtp_helper.h>
46#include <libetpan/mailsmtp_socket.h>
47#include <libetpan/mailsmtp_ssl.h>
48
49
50mailsmtp * mailsmtp_new(size_t progr_rate,
51 progress_function * progr_fun);
52void mailsmtp_free(mailsmtp * session);
53
54int mailsmtp_connect(mailsmtp * session, mailstream * s);
55int mailsmtp_quit(mailsmtp * session);
56
57/**
58 * Tries AUTH with detected method - "better" method first:
59 * CRAM-MD5 -> PLAIN -> LOGIN
60 */
61int mailsmtp_auth(mailsmtp * session, const char * user, const char * pass);
62
63/**
64 * tries to autenticate with the server using given auth-type
65 * returns MAILSMTP_NO_ERROR on success
66 */
67int mailsmtp_auth_type(mailsmtp * session,
68 const char * user, const char * pass, int type);
69
70int mailsmtp_helo(mailsmtp * session);
71int mailsmtp_mail(mailsmtp * session, const char * from);
72int mailsmtp_rcpt(mailsmtp * session, const char * to);
73int mailsmtp_data(mailsmtp * session);
74int mailsmtp_data_message(mailsmtp * session,
75 const char * message,
76 size_t size);
77int mailesmtp_ehlo(mailsmtp * session);
78int mailesmtp_mail(mailsmtp * session,
79 const char * from,
80 int return_full,
81 const char * envid);
82int mailesmtp_rcpt(mailsmtp * session,
83 const char * to,
84 int notify,
85 const char * orcpt);
86int mailesmtp_starttls(mailsmtp * session);
87
88const char * mailsmtp_strerror(int errnum);
89
90#ifdef __cplusplus
91}
92#endif
93
94#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailsmtp_helper.h b/kmicromail/libetpan/include/libetpan/mailsmtp_helper.h
new file mode 100644
index 0000000..6bbe3c9
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailsmtp_helper.h
@@ -0,0 +1,74 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSMTP_HELPER_H
37
38#define MAILSMTP_HELPER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mailsmtp_types.h"
45#include "clist.h"
46
47int mailsmtp_init(mailsmtp * session);
48
49int mailesmtp_send(mailsmtp * session,
50 const char * from,
51 int return_full,
52 const char * envid,
53 clist * addresses,
54 const char * message, size_t size);
55
56int mailsmtp_send(mailsmtp * session,
57 const char * from,
58 clist * addresses,
59 const char * message, size_t size);
60
61clist * esmtp_address_list_new();
62int esmtp_address_list_add(clist * list, char * address,
63 int notify, char * orcpt);
64void esmtp_address_list_free(clist * l);
65
66clist * smtp_address_list_new();
67int smtp_address_list_add(clist * list, char * address);
68void smtp_address_list_free(clist * l);
69
70#ifdef __cplusplus
71}
72#endif
73
74#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailsmtp_socket.h b/kmicromail/libetpan/include/libetpan/mailsmtp_socket.h
new file mode 100644
index 0000000..6691d9e
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailsmtp_socket.h
@@ -0,0 +1,56 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSMTP_SOCKET_H
37
38#define MAILSMTP_SOCKET_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45
46#include <libetpan/mailsmtp_types.h>
47
48int mailsmtp_socket_connect(mailsmtp * session,
49 const char * server, uint16_t port);
50int mailsmtp_socket_starttls(mailsmtp * session);
51
52#ifdef __cplusplus
53}
54#endif
55
56#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailsmtp_ssl.h b/kmicromail/libetpan/include/libetpan/mailsmtp_ssl.h
new file mode 100644
index 0000000..9de9732
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailsmtp_ssl.h
@@ -0,0 +1,55 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSMTP_SSL_H
37
38#define MAILSMTP_SSL_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45
46#include <libetpan/mailsmtp_types.h>
47
48int mailsmtp_ssl_connect(mailsmtp * session,
49 const char * server, uint16_t port);
50
51#ifdef __cplusplus
52}
53#endif
54
55#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailsmtp_types.h b/kmicromail/libetpan/include/libetpan/mailsmtp_types.h
new file mode 100644
index 0000000..b63d5ea
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailsmtp_types.h
@@ -0,0 +1,126 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSMTP_TYPES_H
37
38#define MAILSMTP_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mailstream.h"
45#include "mmapstring.h"
46
47enum {
48 MAILSMTP_NO_ERROR = 0,
49 MAILSMTP_ERROR_UNEXPECTED_CODE,
50 MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE,
51 MAILSMTP_ERROR_STREAM,
52 MAILSMTP_ERROR_HOSTNAME,
53 MAILSMTP_ERROR_NOT_IMPLEMENTED,
54 MAILSMTP_ERROR_ACTION_NOT_TAKEN,
55 MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION,
56 MAILSMTP_ERROR_IN_PROCESSING,
57 MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE,
58 MAILSMTP_ERROR_MAILBOX_UNAVAILABLE,
59 MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED,
60 MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND,
61 MAILSMTP_ERROR_USER_NOT_LOCAL,
62 MAILSMTP_ERROR_TRANSACTION_FAILED,
63 MAILSMTP_ERROR_MEMORY,
64 MAILSMTP_ERROR_AUTH_NOT_SUPPORTED,
65 MAILSMTP_ERROR_AUTH_LOGIN,
66 MAILSMTP_ERROR_AUTH_REQUIRED,
67 MAILSMTP_ERROR_AUTH_TOO_WEAK,
68 MAILSMTP_ERROR_AUTH_TRANSITION_NEEDED,
69 MAILSMTP_ERROR_AUTH_TEMPORARY_FAILTURE,
70 MAILSMTP_ERROR_AUTH_ENCRYPTION_REQUIRED,
71 MAILSMTP_ERROR_STARTTLS_TEMPORARY_FAILURE,
72 MAILSMTP_ERROR_STARTTLS_NOT_SUPPORTED,
73 MAILSMTP_ERROR_CONNECTION_REFUSED
74};
75
76enum {
77 MAILSMTP_AUTH_NOT_CHECKED = 0,
78 MAILSMTP_AUTH_CHECKED = 1,
79 MAILSMTP_AUTH_CRAM_MD5 = 2,
80 MAILSMTP_AUTH_PLAIN = 4,
81 MAILSMTP_AUTH_LOGIN = 8
82};
83
84enum {
85 MAILSMTP_ESMTP = 1,
86 MAILSMTP_ESMTP_EXPN = 2,
87 MAILSMTP_ESMTP_8BITMIME = 4,
88 MAILSMTP_ESMTP_SIZE = 8,
89 MAILSMTP_ESMTP_ETRN = 16,
90 MAILSMTP_ESMTP_STARTTLS = 32,
91 MAILSMTP_ESMTP_DSN = 64,
92};
93
94struct mailsmtp {
95 mailstream * stream;
96
97 size_t progr_rate;
98 progress_function * progr_fun;
99
100 char * response;
101
102 MMAPString * line_buffer;
103 MMAPString * response_buffer;
104
105 int esmtp; // contains flags MAILSMTP_ESMTP_*
106 int auth; // contains flags MAILSMTP_AUTH_*
107};
108
109typedef struct mailsmtp mailsmtp;
110
111#define MAILSMTP_DSN_NOTIFY_SUCCESS 1
112#define MAILSMTP_DSN_NOTIFY_FAILURE 2
113#define MAILSMTP_DSN_NOTIFY_DELAY 4
114#define MAILSMTP_DSN_NOTIFY_NEVER 8
115
116struct esmtp_address {
117 char * address;
118 int notify;
119 char * orcpt;
120};
121
122#ifdef __cplusplus
123}
124#endif
125
126#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailstorage.h b/kmicromail/libetpan/include/libetpan/mailstorage.h
new file mode 100644
index 0000000..d56aef1
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailstorage.h
@@ -0,0 +1,98 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAIL_STORAGE_H
37
38#define MAIL_STORAGE_H
39
40#include <libetpan/maildriver_types.h>
41#include <libetpan/mailstorage_types.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47/* storage */
48
49/*
50 mailstorage_new
51
52 This function creates an empty storage. This storage have to be initialized.
53 The "driver" and "data" fields should be initialized.
54
55 @param id is the name of the storage. It can be NULL.
56 The given parameter is no more needed when the creation is finished.
57 The given string is duplicated.
58
59 @return The mail storage is returned.
60*/
61
62struct mailstorage * mailstorage_new(char * sto_id);
63
64void mailstorage_free(struct mailstorage * storage);
65
66/*
67 session will be initialized on success.
68*/
69
70int mailstorage_connect(struct mailstorage * storage);
71
72void mailstorage_disconnect(struct mailstorage * storage);
73
74
75/* folder */
76
77struct mailfolder * mailfolder_new(struct mailstorage * fld_storage,
78 char * fld_pathname, char * fld_virtual_name);
79
80void mailfolder_free(struct mailfolder * folder);
81
82int mailfolder_add_child(struct mailfolder * parent,
83 struct mailfolder * child);
84
85int mailfolder_detach_parent(struct mailfolder * folder);
86
87int mailfolder_connect(struct mailfolder * folder);
88
89void mailfolder_disconnect(struct mailfolder * folder);
90
91
92#ifdef __cplusplus
93}
94#endif
95
96#endif
97
98
diff --git a/kmicromail/libetpan/include/libetpan/mailstorage_types.h b/kmicromail/libetpan/include/libetpan/mailstorage_types.h
new file mode 100644
index 0000000..5e08f80
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailstorage_types.h
@@ -0,0 +1,203 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSTORAGE_TYPES_H
37
38#define MAILSTORAGE_TYPES_H
39
40#include <libetpan/maildriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46struct mailstorage;
47
48typedef struct mailstorage_driver mailstorage_driver;
49
50
51/*
52 There is three kinds of identities :
53 - storage
54 - folders
55 - session
56
57 A storage (struct mailstorage) represents whether a server or
58 a main path,
59
60 A storage can be an IMAP server, the root path of a MH or a mbox file.
61
62 Folders (struct mailfolder) are the mailboxes we can
63 choose in the server or as sub-folder of the main path.
64
65 Folders for IMAP are the IMAP mailboxes, for MH this is one of the
66 folder of the MH storage, for mbox, there is only one folder, the
67 mbox file content;
68
69 A mail session (struct mailsession) is whether a connection to a server
70 or a path that is open. It is the abstraction lower folders and storage.
71 It allow us to send commands.
72
73 We have a session driver for mail session for each kind of storage.
74
75 From a session, we can get a message (struct mailmessage) to read.
76 We have a message driver for each kind of storage.
77*/
78
79/*
80 mailstorage_driver is the driver structure for mail storages
81
82 - name is the name of the driver
83
84 - connect() connects the storage to the remote access or to
85 the path in the local filesystem.
86
87 - get_folder() can have two kinds of behaviour.
88 Either it creates a new session and independant from the session
89 used by the storage and select the given mailbox or
90 it selects the given mailbox in the current session.
91 It depends on the efficiency of the mail driver.
92
93 - uninitialize() frees the data created with mailstorage constructor.
94*/
95
96struct mailstorage_driver {
97 char * sto_name;
98 int (* sto_connect)(struct mailstorage * storage);
99 int (* sto_get_folder_session)(struct mailstorage * storage,
100 char * pathname, mailsession ** result);
101 void (* sto_uninitialize)(struct mailstorage * storage);
102};
103
104/*
105 mailstorage is the data structure for a storage
106
107 - id is the name of the storage, it can be NULL.
108
109 - data is the data specific to the driver.
110 This is the internal state of the storage.
111
112 - session is the session related to the storage.
113
114 - driver is the driver for the storage.
115
116 - shared_folders is the list of folders returned by the storage.
117*/
118
119struct mailstorage {
120 char * sto_id;
121 void * sto_data;
122 mailsession * sto_session;
123 mailstorage_driver * sto_driver;
124 clist * sto_shared_folders; /* list of (struct mailfolder *) */
125
126 void * sto_user_data;
127};
128
129
130
131/*
132 mailfolder is the data structure for a mailbox
133
134 - pathname is the path of the mailbox on the storage
135
136 - virtual_name is the folder identifier, it can be a path,
137 a name or NULL.
138
139 - storage is the storage to which the folder belongs to.
140
141 - session is the session related to the folder. It can be
142 different of the session of the storage.
143
144 - shared_session is != 0 if the session is the same as the
145 session of the storage.
146
147 - pos is the position of the folder in the "shared_folders" field
148 of the storage.
149
150 folders can be chained into a tree.
151
152 - parent is the parent of the folder.
153
154 - sibling_index is the index of the folder in the list of children
155 of the parent.
156
157 - children is the folder.
158*/
159
160struct mailfolder {
161 char * fld_pathname;
162 char * fld_virtual_name;
163
164 struct mailstorage * fld_storage;
165
166 mailsession * fld_session;
167 int fld_shared_session;
168 clistiter * fld_pos;
169
170 struct mailfolder * fld_parent;
171 unsigned int fld_sibling_index;
172 carray * fld_children; /* array of (struct mailfolder *) */
173
174 void * fld_user_data;
175};
176
177/*
178 this is the type of socket connection
179*/
180
181enum {
182 CONNECTION_TYPE_PLAIN, /* when the connection is plain text */
183 CONNECTION_TYPE_STARTTLS, /* when the connection is first plain,
184 then, we want to switch to
185 TLS (secure connection) */
186 CONNECTION_TYPE_TRY_STARTTLS, /* the connection is first plain,
187 then, we will try to switch to TLS */
188 CONNECTION_TYPE_TLS, /* the connection is over TLS */
189 CONNECTION_TYPE_COMMAND, /* the connection is over a shell command */
190 CONNECTION_TYPE_COMMAND_STARTTLS, /* the connection is over a shell
191 command and STARTTLS will be used */
192 CONNECTION_TYPE_COMMAND_TRY_STARTTLS, /* the connection is over
193 a shell command and STARTTLS will
194 be tried */
195 CONNECTION_TYPE_COMMAND_TLS, /* the connection is over a shell
196 command in TLS */
197};
198
199#ifdef __cplusplus
200}
201#endif
202
203#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailstream.h b/kmicromail/libetpan/include/libetpan/mailstream.h
new file mode 100644
index 0000000..a4e35cd
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailstream.h
@@ -0,0 +1,73 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSTREAM_H
37
38#define MAILSTREAM_H
39
40#include <sys/time.h>
41
42#include <libetpan/mailstream_low.h>
43#include <libetpan/mailstream_helper.h>
44#include <libetpan/mailstream_socket.h>
45#include <libetpan/mailstream_ssl.h>
46#include <libetpan/mailstream_types.h>
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52mailstream * mailstream_new(mailstream_low * low, size_t buffer_size);
53ssize_t mailstream_write(mailstream * s, const void * buf, size_t count);
54ssize_t mailstream_read(mailstream * s, void * buf, size_t count);
55int mailstream_close(mailstream * s);
56int mailstream_flush(mailstream * s);
57ssize_t mailstream_feed_read_buffer(mailstream * s);
58mailstream_low * mailstream_get_low(mailstream * s);
59void mailstream_set_low(mailstream * s, mailstream_low * low);
60
61#ifdef LIBETPAN_MAILSTREAM_DEBUG
62extern int mailstream_debug;
63#endif
64
65#define LIBETPAN_MAILSTREAM_NETWORK_DELAY
66extern struct timeval mailstream_network_delay;
67
68#ifdef __cplusplus
69}
70#endif
71
72#endif
73
diff --git a/kmicromail/libetpan/include/libetpan/mailstream_helper.h b/kmicromail/libetpan/include/libetpan/mailstream_helper.h
new file mode 100644
index 0000000..d030b1d
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailstream_helper.h
@@ -0,0 +1,70 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSTREAM_HELPER_H
37
38#define MAILSTREAM_HELPER_H
39
40#include <libetpan/mmapstring.h>
41#include <libetpan/mailstream.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47char * mailstream_read_line(mailstream * stream, MMAPString * line);
48
49char * mailstream_read_line_append(mailstream * stream, MMAPString * line);
50
51char * mailstream_read_line_remove_eol(mailstream * stream, MMAPString * line);
52
53char * mailstream_read_multiline(mailstream * s, size_t size,
54 MMAPString * stream_buffer,
55 MMAPString * multiline_buffer,
56 size_t progr_rate,
57 progress_function * progr_fun);
58
59int mailstream_is_end_multiline(const char * line);
60
61int mailstream_send_data(mailstream * s, const char * message,
62 size_t size,
63 size_t progr_rate,
64 progress_function * progr_fun);
65
66#ifdef __cplusplus
67}
68#endif
69
70#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailstream_low.h b/kmicromail/libetpan/include/libetpan/mailstream_low.h
new file mode 100644
index 0000000..fb8914c
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailstream_low.h
@@ -0,0 +1,62 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSTREAM_LOW_H
37
38#define MAILSTREAM_LOW_H
39
40#include <sys/types.h>
41#include <libetpan/mailstream_types.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47/* general functions */
48
49mailstream_low * mailstream_low_new(void * data,
50 mailstream_low_driver * driver);
51ssize_t mailstream_low_write(mailstream_low * s,
52 const void * buf, size_t count);
53ssize_t mailstream_low_read(mailstream_low * s, void * buf, size_t count);
54int mailstream_low_close(mailstream_low * s);
55int mailstream_low_get_fd(mailstream_low * s);
56void mailstream_low_free(mailstream_low * s);
57
58#ifdef __cplusplus
59}
60#endif
61
62#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailstream_socket.h b/kmicromail/libetpan/include/libetpan/mailstream_socket.h
new file mode 100644
index 0000000..6a26e33
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailstream_socket.h
@@ -0,0 +1,61 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSTREAM_SOCKET_H
37
38#define MAILSTREAM_SOCKET_H
39
40#include <libetpan/mailstream.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/* socket */
47
48extern mailstream_low_driver * mailstream_socket_driver;
49
50mailstream_low * mailstream_low_socket_open(int fd);
51mailstream * mailstream_socket_open(int fd);
52
53struct mailstream_socket_data {
54 int fd;
55};
56
57#ifdef __cplusplus
58}
59#endif
60
61#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailstream_ssl.h b/kmicromail/libetpan/include/libetpan/mailstream_ssl.h
new file mode 100644
index 0000000..a37b3d4
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailstream_ssl.h
@@ -0,0 +1,59 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSTREAM_SSL_H
37
38#define MAILSTREAM_SSL_H
39
40#include <libetpan/mailstream.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/* socket */
47
48#ifdef USE_SSL
49extern mailstream_low_driver * mailstream_ssl_driver;
50#endif
51
52mailstream_low * mailstream_low_ssl_open(int fd);
53mailstream * mailstream_ssl_open(int fd);
54
55#ifdef __cplusplus
56}
57#endif
58
59#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailstream_types.h b/kmicromail/libetpan/include/libetpan/mailstream_types.h
new file mode 100644
index 0000000..2165149
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailstream_types.h
@@ -0,0 +1,87 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSTREAM_TYPES_H
37
38#define MAILSTREAM_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#define LIBETPAN_MAILSTREAM_DEBUG
45
46struct _mailstream;
47
48typedef struct _mailstream mailstream;
49
50struct _mailstream_low;
51
52typedef struct _mailstream_low mailstream_low;
53
54struct _mailstream {
55 size_t buffer_max_size;
56
57 char * write_buffer;
58 size_t write_buffer_len;
59
60 char * read_buffer;
61 size_t read_buffer_len;
62
63 mailstream_low * low;
64};
65
66struct mailstream_low_driver {
67 ssize_t (* mailstream_read)(mailstream_low *, void *, size_t);
68 ssize_t (* mailstream_write)(mailstream_low *, const void *, size_t);
69 int (* mailstream_close)(mailstream_low *);
70 int (* mailstream_get_fd)(mailstream_low *);
71 void (* mailstream_free)(mailstream_low *);
72};
73
74typedef struct mailstream_low_driver mailstream_low_driver;
75
76struct _mailstream_low {
77 void * data;
78 mailstream_low_driver * driver;
79};
80
81typedef void progress_function(size_t current, size_t maximum);
82
83#ifdef __cplusplus
84}
85#endif
86
87#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailthread.h b/kmicromail/libetpan/include/libetpan/mailthread.h
new file mode 100644
index 0000000..e4e33ff
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailthread.h
@@ -0,0 +1,108 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILTHREAD_H
37
38#define MAILTHREAD_H
39
40#include <libetpan/mailthread_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 mail_build_thread constructs a tree with the message using the
48 given style.
49
50 @param type is the type of threading to apply, the value can be
51 MAIL_THREAD_REFERENCES, MAIL_THREAD_REFERENCES_NO_SUBJECT or
52 MAIL_THREAD_ORDEREDSUBJECT.
53
54 @param default_from is the default charset to use whenever the
55 subject is not tagged with a charset. "US-ASCII" can be used
56 if you don't know what to use.
57
58 @param env_list is the message list (with header fields fetched)
59 to use to build the message tree.
60
61 @param result * result) will contain the resulting message tree.
62
63 @param if comp_func is NULL, no sorting algorithm is used.
64
65 @return MAIL_NO_ERROR is returned on success, MAIL_ERROR_XXX is returned
66 on error
67*/
68
69int mail_build_thread(int type, char * default_from,
70 struct mailmessage_list * env_list,
71 struct mailmessage_tree ** result,
72 int (* comp_func)(struct mailmessage_tree **,
73 struct mailmessage_tree **));
74
75/*
76 mail_thread_sort sort the messages in the message tree, using the
77 given sort function.
78
79 @param tree is the message tree to sort.
80
81 @param comp_func is the sort function to use (this is the same kind of
82 functions than those used for qsort()). mailthread_tree_timecomp can be
83 used for default sort.
84
85 @param sort_sub if this value is 0, only the children of the root message
86 are sorted.
87*/
88
89int mail_thread_sort(struct mailmessage_tree * tree,
90 int (* comp_func)(struct mailmessage_tree **,
91 struct mailmessage_tree **),
92 int sort_sub);
93
94/*
95 mailthread_tree_timecomp is the default sort function.
96
97 The message are compared by date, then by message numbers.
98 The tree are given in (* ptree1) and (* ptree2).
99*/
100
101int mailthread_tree_timecomp(struct mailmessage_tree ** ptree1,
102 struct mailmessage_tree ** ptree2);
103
104#ifdef __cplusplus
105}
106#endif
107
108#endif
diff --git a/kmicromail/libetpan/include/libetpan/mailthread_types.h b/kmicromail/libetpan/include/libetpan/mailthread_types.h
new file mode 100644
index 0000000..5ef7b46
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mailthread_types.h
@@ -0,0 +1,63 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILTHREAD_TYPES_H
37
38#define MAILTHREAD_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/maildriver_types.h>
45#include <libetpan/mailmessage_types.h>
46
47/*
48 This is the type of tree construction to apply.
49*/
50
51enum {
52 MAIL_THREAD_REFERENCES, /* this is threading using
53 References fields only) */
54 MAIL_THREAD_REFERENCES_NO_SUBJECT, /* this is threading using References
55 fields, then subject */
56 MAIL_THREAD_ORDEREDSUBJECT, /* this is threading using only subject */
57};
58
59#ifdef __cplusplus
60}
61#endif
62
63#endif
diff --git a/kmicromail/libetpan/include/libetpan/mboxdriver.h b/kmicromail/libetpan/include/libetpan/mboxdriver.h
new file mode 100644
index 0000000..c598026
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mboxdriver.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MBOXDRIVER_H
37
38#define MBOXDRIVER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mboxdriver_types.h>
45
46extern mailsession_driver * mbox_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/mboxdriver_cached.h b/kmicromail/libetpan/include/libetpan/mboxdriver_cached.h
new file mode 100644
index 0000000..b0d8dbf
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mboxdriver_cached.h
@@ -0,0 +1,54 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MBOXDRIVER_CACHED_H
37
38#define MBOXDRIVER_CACHED_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/mboxdriver_types.h>
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48extern mailsession_driver * mbox_cached_session_driver;
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/kmicromail/libetpan/include/libetpan/mboxdriver_cached_message.h b/kmicromail/libetpan/include/libetpan/mboxdriver_cached_message.h
new file mode 100644
index 0000000..a6673b3
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mboxdriver_cached_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MBOXDRIVER_CACHED_MESSAGE_H
37
38#define MBOXDRIVER_CACHED_MESSAGE_H
39
40#include <libetpan/mailmessage.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * mbox_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/mboxdriver_message.h b/kmicromail/libetpan/include/libetpan/mboxdriver_message.h
new file mode 100644
index 0000000..cdabd23
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mboxdriver_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MBOXDRIVER_MESSAGE_H
37
38#define MBOXDRIVER_MESSAGE_H
39
40#include <libetpan/mboxdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * mbox_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/mboxdriver_types.h b/kmicromail/libetpan/include/libetpan/mboxdriver_types.h
new file mode 100644
index 0000000..be31ea3
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mboxdriver_types.h
@@ -0,0 +1,107 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MBOXDRIVER_TYPES_H
37
38#define MBOXDRIVER_TYPES_H
39
40#include <libetpan/maildriver_types.h>
41#include <libetpan/mailmbox.h>
42#include <libetpan/mailstorage_types.h>
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48/* mbox driver */
49
50enum {
51 MBOXDRIVER_SET_READ_ONLY = 1,
52 MBOXDRIVER_SET_NO_UID,
53};
54
55struct mbox_session_state_data {
56 struct mailmbox_folder * mbox_folder;
57 int mbox_force_read_only;
58 int mbox_force_no_uid;
59};
60
61/* cached version */
62
63enum {
64 /* the mapping of the parameters should be the same as for mbox */
65 MBOXDRIVER_CACHED_SET_READ_ONLY = 1,
66 MBOXDRIVER_CACHED_SET_NO_UID,
67 /* cache specific */
68 MBOXDRIVER_CACHED_SET_CACHE_DIRECTORY,
69 MBOXDRIVER_CACHED_SET_FLAGS_DIRECTORY,
70};
71
72struct mbox_cached_session_state_data {
73 mailsession * mbox_ancestor;
74 char * mbox_quoted_mb;
75 char mbox_cache_directory[PATH_MAX];
76 char mbox_flags_directory[PATH_MAX];
77 struct mail_flags_store * mbox_flags_store;
78};
79
80/* mbox storage */
81
82/*
83 mbox_mailstorage is the state data specific to the mbox storage.
84
85 - pathname is the filename that contains the mailbox.
86
87 - cached if this value is != 0, a persistant cache will be
88 stored on local system.
89
90 - cache_directory is the location of the cache.
91
92 - flags_directory is the location of the flags.
93*/
94
95struct mbox_mailstorage {
96 char * mbox_pathname;
97
98 int mbox_cached;
99 char * mbox_cache_directory;
100 char * mbox_flags_directory;
101};
102
103#ifdef __cplusplus
104}
105#endif
106
107#endif
diff --git a/kmicromail/libetpan/include/libetpan/mboxstorage.h b/kmicromail/libetpan/include/libetpan/mboxstorage.h
new file mode 100644
index 0000000..e5e83ce
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mboxstorage.h
@@ -0,0 +1,69 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MBOXSTORAGE_H
37
38#define MBOXSTORAGE_H
39
40#include <libetpan/mboxdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 mbox_mailstorage_init is the constructor for a mbox storage.
48
49 @param storage this is the storage to initialize.
50
51 @param pathname is the filename that contains the mailbox.
52
53 @param cached if this value is != 0, a persistant cache will be
54 stored on local system.
55
56 @param cache_directory is the location of the cache
57
58 @param flags_directory is the location of the flags
59*/
60
61int mbox_mailstorage_init(struct mailstorage * storage,
62 char * mb_pathname, int mb_cached,
63 char * mb_cache_directory, char * mb_flags_directory);
64
65#ifdef __cplusplus
66}
67#endif
68
69#endif
diff --git a/kmicromail/libetpan/include/libetpan/mhdriver.h b/kmicromail/libetpan/include/libetpan/mhdriver.h
new file mode 100644
index 0000000..a82b9c1
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mhdriver.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MHDRIVER_H
37
38#define MHDRIVER_H
39
40#include <libetpan/maildriver.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * mh_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/mhdriver_cached.h b/kmicromail/libetpan/include/libetpan/mhdriver_cached.h
new file mode 100644
index 0000000..4a07e7d
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mhdriver_cached.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MHDRIVER_CACHED_H
37
38#define MHDRIVER_CACHED_H
39
40#include <libetpan/mhdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * mh_cached_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/mhdriver_cached_message.h b/kmicromail/libetpan/include/libetpan/mhdriver_cached_message.h
new file mode 100644
index 0000000..f3ed089
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mhdriver_cached_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MHDRIVER_CACHED_MESSAGE_H
37
38#define MHDRIVER_CACHED_MESSAGE_H
39
40#include <libetpan/mhdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * mh_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/mhdriver_message.h b/kmicromail/libetpan/include/libetpan/mhdriver_message.h
new file mode 100644
index 0000000..a7cb2cf
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mhdriver_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MHDRIVER_MESSAGE_H
37
38#define MHDRIVER_MESSAGE_H
39
40#include <libetpan/mhdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * mh_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/mhdriver_types.h b/kmicromail/libetpan/include/libetpan/mhdriver_types.h
new file mode 100644
index 0000000..09c6cc6
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mhdriver_types.h
@@ -0,0 +1,100 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MHDRIVER_TYPES_H
37
38#define MHDRIVER_TYPES_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/maildriver_types.h>
43#include <libetpan/mailmh.h>
44#include <libetpan/clist.h>
45#include <libetpan/generic_cache_types.h>
46#include <libetpan/mailstorage_types.h>
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52struct mh_session_state_data {
53 struct mailmh * mh_session;
54
55 struct mailmh_folder * mh_cur_folder;
56
57 clist * mh_subscribed_list;
58};
59
60enum {
61 MHDRIVER_CACHED_SET_CACHE_DIRECTORY = 1,
62 MHDRIVER_CACHED_SET_FLAGS_DIRECTORY,
63};
64
65struct mh_cached_session_state_data {
66 mailsession * mh_ancestor;
67 char * mh_quoted_mb;
68 char mh_cache_directory[PATH_MAX];
69 char mh_flags_directory[PATH_MAX];
70 struct mail_flags_store * mh_flags_store;
71};
72
73/* mh storage */
74
75/*
76 mh_mailstorage is the state data specific to the MH storage.
77
78 - pathname is the root path of the MH storage.
79
80 - cached if this value is != 0, a persistant cache will be
81 stored on local system.
82
83 - cache_directory is the location of the cache.
84
85 - flags_directory is the location of the flags.
86*/
87
88struct mh_mailstorage {
89 char * mh_pathname;
90
91 int mh_cached;
92 char * mh_cache_directory;
93 char * mh_flags_directory;
94};
95
96#ifdef __cplusplus
97}
98#endif
99
100#endif
diff --git a/kmicromail/libetpan/include/libetpan/mhstorage.h b/kmicromail/libetpan/include/libetpan/mhstorage.h
new file mode 100644
index 0000000..245bc81
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mhstorage.h
@@ -0,0 +1,67 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MHSTORAGE_H
37
38#define MHSTORAGE_H
39
40#include <libetpan/mhdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47 mh_mailstorage_init is the constructor for a MH storage
48
49 @param pathname is the filename the root path of the MH storage.
50
51 @param cached if this value is != 0, a persistant cache will be
52 stored on local system.
53
54 @param cache_directory is the location of the cache.
55
56 @param flags_directory is the location of the flags.
57*/
58
59int mh_mailstorage_init(struct mailstorage * storage,
60 char * mh_pathname, int mh_cached,
61 char * mh_cache_directory, char * mh_flags_directory);
62
63#ifdef __cplusplus
64}
65#endif
66
67#endif
diff --git a/kmicromail/libetpan/include/libetpan/mime_message_driver.h b/kmicromail/libetpan/include/libetpan/mime_message_driver.h
new file mode 100644
index 0000000..ffcdd5c
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mime_message_driver.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MIME_MESSAGE_DRIVER_H
37
38#define MIME_MESSAGE_DRIVER_H
39
40#include <libetpan/mailmessage.h>
41
42#define LIBETPAN_MIME_MESSAGE
43
44extern mailmessage_driver * mime_message_driver;
45
46mailmessage * mime_message_init(struct mailmime * mime);
47
48void mime_message_detach_mime(mailmessage * msg);
49
50int mime_message_set_tmpdir(mailmessage * msg, char * tmpdir);
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/mmapstring.h b/kmicromail/libetpan/include/libetpan/mmapstring.h
new file mode 100644
index 0000000..6d7227d
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/mmapstring.h
@@ -0,0 +1,136 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef __MMAP_STRING_H__
37
38#define __MMAP_STRING_H__
39
40#include <sys/types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47#define TMPDIR "/tmp"
48*/
49
50typedef struct _MMAPString MMAPString;
51
52struct _MMAPString
53{
54 char * str;
55 size_t len;
56 size_t allocated_len;
57 int fd;
58 size_t mmapped_size;
59 /*
60 char * old_non_mmapped_str;
61 */
62};
63
64/* configure location of mmaped files */
65
66void mmap_string_set_tmpdir(char * directory);
67
68/* Strings
69 */
70
71MMAPString * mmap_string_new (const char * init);
72
73MMAPString * mmap_string_new_len (const char * init,
74 size_t len);
75
76MMAPString * mmap_string_sized_new (size_t dfl_size);
77
78void mmap_string_free (MMAPString * string);
79
80MMAPString * mmap_string_assign (MMAPString * string,
81 const char * rval);
82
83MMAPString * mmap_string_truncate (MMAPString *string,
84 size_t len);
85
86MMAPString * mmap_string_set_size (MMAPString * string,
87 size_t len);
88
89MMAPString * mmap_string_insert_len (MMAPString * string,
90 size_t pos,
91 const char * val,
92 size_t len);
93
94MMAPString * mmap_string_append (MMAPString * string,
95 const char * val);
96
97MMAPString * mmap_string_append_len (MMAPString * string,
98 const char * val,
99 size_t len);
100
101MMAPString * mmap_string_append_c (MMAPString * string,
102 char c);
103
104MMAPString * mmap_string_prepend (MMAPString * string,
105 const char * val);
106
107MMAPString * mmap_string_prepend_c (MMAPString * string,
108 char c);
109
110MMAPString * mmap_string_prepend_len (MMAPString * string,
111 const char * val,
112 size_t len);
113
114MMAPString * mmap_string_insert (MMAPString * string,
115 size_t pos,
116 const char * val);
117
118MMAPString * mmap_string_insert_c (MMAPString *string,
119 size_t pos,
120 char c);
121
122MMAPString * mmap_string_erase(MMAPString * string,
123 size_t pos,
124 size_t len);
125
126void mmap_string_set_ceil(size_t ceil);
127
128int mmap_string_ref(MMAPString * string);
129int mmap_string_unref(char * str);
130
131#ifdef __cplusplus
132}
133#endif
134
135
136#endif /* __MMAP_STRING_H__ */
diff --git a/kmicromail/libetpan/include/libetpan/newsnntp.h b/kmicromail/libetpan/include/libetpan/newsnntp.h
new file mode 100644
index 0000000..13360d0
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/newsnntp.h
@@ -0,0 +1,188 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NEWSNNTP_H
37
38#define NEWSNNTP_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45#include <sys/types.h>
46#include <time.h>
47
48#include <libetpan/clist.h>
49#include <libetpan/mailstream.h>
50#include <libetpan/newsnntp_socket.h>
51#include <libetpan/newsnntp_ssl.h>
52#include <libetpan/newsnntp_types.h>
53
54
55newsnntp * newsnntp_new(size_t nntp_progr_rate,
56 progress_function * nntp_progr_fun);
57void newsnntp_free(newsnntp * f);
58
59int newsnntp_quit(newsnntp * f);
60int newsnntp_connect(newsnntp * f, mailstream * s);
61
62int newsnntp_head(newsnntp * f, uint32_t index, char ** result,
63 size_t * result_len);
64int newsnntp_article(newsnntp * f, uint32_t index, char ** result,
65 size_t * result_len);
66int newsnntp_body(newsnntp * f, uint32_t index, char ** result,
67 size_t * result_len);
68
69void newsnntp_head_free(char * str);
70void newsnntp_article_free(char * str);
71void newsnntp_body_free(char * str);
72
73int newsnntp_mode_reader(newsnntp * f);
74
75int newsnntp_date(newsnntp * f, struct tm * tm);
76
77int newsnntp_authinfo_generic(newsnntp * f, const char * authentificator,
78 const char * arguments);
79
80int newsnntp_authinfo_username(newsnntp * f, const char * username);
81int newsnntp_authinfo_password(newsnntp * f, const char * password);
82
83int newsnntp_post(newsnntp * f, const char * message, size_t size);
84
85
86
87
88
89
90/******************* requests ******************************/
91
92int newsnntp_group(newsnntp * f, const char * groupname,
93 struct newsnntp_group_info ** info);
94void newsnntp_group_free(struct newsnntp_group_info * info);
95
96/*
97 elements are struct newsnntp_group_info *
98 */
99
100int newsnntp_list(newsnntp * f, clist ** result);
101void newsnntp_list_free(clist * l);
102
103/*
104 elements are char *
105*/
106
107int newsnntp_list_overview_fmt(newsnntp * f, clist ** result);
108void newsnntp_list_overview_fmt_free(clist * l);
109
110/*
111 elements are struct newsnntp_group_info *
112*/
113
114int newsnntp_list_active(newsnntp * f, const char * wildcard, clist ** result);
115void newsnntp_list_active_free(clist * l);
116
117/*
118 elements are struct newsnntp_group_time *
119*/
120
121int newsnntp_list_active_times(newsnntp * f, clist ** result);
122void newsnntp_list_active_times_free(clist * l);
123
124/*
125 elements are struct newsnntp_distrib_value_meaning *
126*/
127
128int newsnntp_list_distribution(newsnntp * f, clist ** result);
129void newsnntp_list_distribution_free(clist * l);
130
131/*
132 elements are struct newsnntp_distrib_default_value *
133*/
134
135int newsnntp_list_distrib_pats(newsnntp * f, clist ** result);
136void newsnntp_list_distrib_pats_free(clist * l);
137
138/*
139 elements are struct newsnntp_group_description *
140*/
141
142int newsnntp_list_newsgroups(newsnntp * f, const char * pattern,
143 clist ** result);
144void newsnntp_list_newsgroups_free(clist * l);
145
146/*
147 elements are char *
148*/
149
150int newsnntp_list_subscriptions(newsnntp * f, clist ** result);
151void newsnntp_list_subscriptions_free(clist * l);
152
153/*
154 elements are uint32_t *
155*/
156
157int newsnntp_listgroup(newsnntp * f, const char * group_name,
158 clist ** result);
159void newsnntp_listgroup_free(clist * l);
160
161/*
162 elements are struct newsnntp_xhdr_resp_item *
163*/
164
165int newsnntp_xhdr_single(newsnntp * f, const char * header, uint32_t article,
166 clist ** result);
167int newsnntp_xhdr_range(newsnntp * f, const char * header,
168 uint32_t rangeinf, uint32_t rangesup,
169 clist ** result);
170void newsnntp_xhdr_free(clist * l);
171
172/*
173 elements are struct newsnntp_xover_resp_item *
174*/
175
176int newsnntp_xover_single(newsnntp * f, uint32_t article,
177 struct newsnntp_xover_resp_item ** result);
178int newsnntp_xover_range(newsnntp * f, uint32_t rangeinf, uint32_t rangesup,
179 clist ** result);
180void newsnntp_xover_free(clist * l);
181void xover_resp_item_free(struct newsnntp_xover_resp_item * n);
182void newsnntp_xover_resp_list_free(clist * l);
183
184#ifdef __cplusplus
185}
186#endif
187
188#endif
diff --git a/kmicromail/libetpan/include/libetpan/newsnntp_socket.h b/kmicromail/libetpan/include/libetpan/newsnntp_socket.h
new file mode 100644
index 0000000..fd44b44
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/newsnntp_socket.h
@@ -0,0 +1,55 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NEWSNNTP_SOCKET_H
37
38#define NEWSNNTP_SOCKET_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <sys/types.h>
45#include <inttypes.h>
46
47#include <libetpan/newsnntp_types.h>
48
49int newsnntp_socket_connect(newsnntp * f, const char * server, uint16_t port);
50
51#ifdef __cplusplus
52}
53#endif
54
55#endif
diff --git a/kmicromail/libetpan/include/libetpan/newsnntp_ssl.h b/kmicromail/libetpan/include/libetpan/newsnntp_ssl.h
new file mode 100644
index 0000000..59eace5
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/newsnntp_ssl.h
@@ -0,0 +1,55 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NEWSNNTP_SSL_H
37
38#define NEWSNNTP_SSL_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <sys/types.h>
45#include <inttypes.h>
46
47#include <libetpan/newsnntp_types.h>
48
49int newsnntp_ssl_connect(newsnntp * f, const char * server, uint16_t port);
50
51#ifdef __cplusplus
52}
53#endif
54
55#endif
diff --git a/kmicromail/libetpan/include/libetpan/newsnntp_types.h b/kmicromail/libetpan/include/libetpan/newsnntp_types.h
new file mode 100644
index 0000000..0501088
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/newsnntp_types.h
@@ -0,0 +1,144 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NEWSNNTP_TYPES_H
37
38#define NEWSNNTP_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45#include <libetpan/clist.h>
46
47#include <libetpan/mailstream.h>
48#include <libetpan/mmapstring.h>
49
50enum {
51 NEWSNNTP_NO_ERROR = 0,
52 NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME,
53 NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD,
54 NEWSNNTP_ERROR_STREAM,
55 NEWSNNTP_ERROR_UNEXPECTED,
56 NEWSNNTP_ERROR_NO_NEWSGROUP_SELECTED,
57 NEWSNNTP_ERROR_NO_ARTICLE_SELECTED,
58 NEWSNNTP_ERROR_INVALID_ARTICLE_NUMBER,
59 NEWSNNTP_ERROR_ARTICLE_NOT_FOUND,
60 NEWSNNTP_ERROR_UNEXPECTED_RESPONSE,
61 NEWSNNTP_ERROR_INVALID_RESPONSE,
62 NEWSNNTP_ERROR_NO_SUCH_NEWS_GROUP,
63 NEWSNNTP_ERROR_POSTING_NOT_ALLOWED,
64 NEWSNNTP_ERROR_POSTING_FAILED,
65 NEWSNNTP_ERROR_PROGRAM_ERROR,
66 NEWSNNTP_ERROR_NO_PERMISSION,
67 NEWSNNTP_ERROR_COMMAND_NOT_UNDERSTOOD,
68 NEWSNNTP_ERROR_COMMAND_NOT_SUPPORTED,
69 NEWSNNTP_ERROR_CONNECTION_REFUSED,
70 NEWSNNTP_ERROR_MEMORY,
71 NEWSNNTP_ERROR_AUTHENTICATION_REJECTED,
72 NEWSNNTP_ERROR_BAD_STATE,
73};
74
75struct newsnntp
76{
77 mailstream * nntp_stream;
78
79 int nntp_readonly;
80
81 uint32_t nntp_progr_rate;
82 progress_function * nntp_progr_fun;
83
84 MMAPString * nntp_stream_buffer;
85 MMAPString * nntp_response_buffer;
86
87 char * nntp_response;
88};
89
90typedef struct newsnntp newsnntp;
91
92struct newsnntp_group_info
93{
94 char * grp_name;
95 uint32_t grp_first;
96 uint32_t grp_last;
97 uint32_t grp_count;
98 char grp_type;
99};
100
101struct newsnntp_group_time {
102 char * grp_name;
103 uint32_t grp_date;
104 char * grp_email;
105};
106
107struct newsnntp_distrib_value_meaning {
108 char * dst_value;
109 char * dst_meaning;
110};
111
112struct newsnntp_distrib_default_value {
113 uint32_t dst_weight;
114 char * dst_group_pattern;
115 char * dst_value;
116};
117
118struct newsnntp_group_description {
119 char * grp_name;
120 char * grp_description;
121};
122
123struct newsnntp_xhdr_resp_item {
124 uint32_t hdr_article;
125 char * hdr_value;
126};
127
128struct newsnntp_xover_resp_item {
129 uint32_t ovr_article;
130 char * ovr_subject;
131 char * ovr_author;
132 char * ovr_date;
133 char * ovr_message_id;
134 char * ovr_references;
135 size_t ovr_size;
136 uint32_t ovr_line_count;
137 clist * ovr_others;
138};
139
140#ifdef __cplusplus
141}
142#endif
143
144#endif
diff --git a/kmicromail/libetpan/include/libetpan/nntpdriver.h b/kmicromail/libetpan/include/libetpan/nntpdriver.h
new file mode 100644
index 0000000..45bfeab
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/nntpdriver.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NNTPDRIVER_H
37
38#define NNTPDRIVER_H
39
40#include <libetpan/nntpdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * nntp_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/nntpdriver_cached.h b/kmicromail/libetpan/include/libetpan/nntpdriver_cached.h
new file mode 100644
index 0000000..feb576b
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/nntpdriver_cached.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NNTPDRIVER_CACHED_H
37
38#define NNTPDRIVER_CACHED_H
39
40#include <libetpan/nntpdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * nntp_cached_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/nntpdriver_cached_message.h b/kmicromail/libetpan/include/libetpan/nntpdriver_cached_message.h
new file mode 100644
index 0000000..c12f479
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/nntpdriver_cached_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include <libetpan/mailmessage_types.h>
37
38#ifndef NNTPDRIVER_CACHED_MESSAGE_H
39
40#define NNTPDRIVER_CACHED_MESSAGE_H
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * nntp_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/nntpdriver_message.h b/kmicromail/libetpan/include/libetpan/nntpdriver_message.h
new file mode 100644
index 0000000..3b12a2d
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/nntpdriver_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NNTPDRIVER_MESSAGE_H
37
38#define NNTPDRIVER_MESSAGE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/nntpdriver_types.h>
45
46extern mailmessage_driver * nntp_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/nntpdriver_types.h b/kmicromail/libetpan/include/libetpan/nntpdriver_types.h
new file mode 100644
index 0000000..6492788
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/nntpdriver_types.h
@@ -0,0 +1,146 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NNTPDRIVER_TYPES_H
37
38#define NNTPDRIVER_TYPES_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/maildriver_types.h>
43#include <libetpan/newsnntp.h>
44#include <libetpan/clist.h>
45#include <libetpan/generic_cache_types.h>
46#include <libetpan/mailstorage_types.h>
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52/* NNTP driver for session */
53
54enum {
55 NNTPDRIVER_SET_MAX_ARTICLES = 1,
56};
57
58struct nntp_session_state_data {
59 newsnntp * nntp_session;
60 char * nntp_userid;
61 char * nntp_password;
62
63 struct newsnntp_group_info * nntp_group_info;
64 char * nntp_group_name;
65
66 clist * nntp_subscribed_list;
67
68 uint32_t nntp_max_articles;
69
70 int nntp_mode_reader;
71};
72
73/* cached NNTP driver for session */
74
75enum {
76 /* the mapping of the parameters should be the same as for nntp */
77 NNTPDRIVER_CACHED_SET_MAX_ARTICLES = 1,
78 /* cache specific */
79 NNTPDRIVER_CACHED_SET_CACHE_DIRECTORY,
80 NNTPDRIVER_CACHED_SET_FLAGS_DIRECTORY,
81};
82
83struct nntp_cached_session_state_data {
84 mailsession * nntp_ancestor;
85 char nntp_cache_directory[PATH_MAX];
86 char nntp_flags_directory[PATH_MAX];
87 struct mail_flags_store * nntp_flags_store;
88};
89
90
91/* nntp storage */
92
93/*
94 nntp_mailstorage is the state data specific to the IMAP4rev1 storage.
95
96 - storage this is the storage to initialize.
97
98 - servername this is the name of the NNTP server
99
100 - port is the port to connect to, on the server.
101 you give 0 to use the default port.
102
103 - connection_type is the type of socket layer to use.
104 The value can be CONNECTION_TYPE_PLAIN or CONNECTION_TYPE_TLS.
105
106 - auth_type is the authenticate mechanism to use.
107 The value can be NNTP_AUTH_TYPE_PLAIN.
108
109 - login is the login of the POP3 account.
110
111 - password is the password of the POP3 account.
112
113 - cached if this value is != 0, a persistant cache will be
114 stored on local system.
115
116 - cache_directory is the location of the cache
117
118 - flags_directory is the location of the flags
119*/
120
121struct nntp_mailstorage {
122 char * nntp_servername;
123 uint16_t nntp_port;
124 char * nntp_command;
125 int nntp_connection_type;
126
127 int nntp_auth_type;
128 char * nntp_login;
129 char * nntp_password;
130
131 int nntp_cached;
132 char * nntp_cache_directory;
133 char * nntp_flags_directory;
134};
135
136/* this is the type of NNTP authentication */
137
138enum {
139 NNTP_AUTH_TYPE_PLAIN, /* plain text authentication */
140};
141
142#ifdef __cplusplus
143}
144#endif
145
146#endif
diff --git a/kmicromail/libetpan/include/libetpan/nntpstorage.h b/kmicromail/libetpan/include/libetpan/nntpstorage.h
new file mode 100644
index 0000000..794c717
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/nntpstorage.h
@@ -0,0 +1,93 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NNTPSTORAGE_H
37
38#define NNTPSTORAGE_H
39
40#include <libetpan/nntpdriver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46
47/*
48 nntp_mailstorage_init is the constructor for a NNTP storage
49
50 @param storage this is the storage to initialize.
51
52 @param servername this is the name of the NNTP server
53
54 @param port is the port to connect to, on the server.
55 you give 0 to use the default port.
56
57 @param command the command used to connect to the server instead of
58 allowing normal TCP connections to be used.
59
60 @param connection_type is the type of socket layer to use.
61 The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
62 CONNECTION_TYPE_TRY_STARTTLS, CONNECTION_TYPE_TLS,
63 CONNECTION_TYPE_COMMAND, CONNECTION_TYPE_COMMAND_STARTTLS,
64 CONNECTION_TYPE_COMMAND_TRY_STARTTLS, CONNECTION_TYPE_COMMAND_TLS,.
65
66 @param auth_type is the authenticate mechanism to use.
67 The value can be NNTP_AUTH_TYPE_PLAIN.
68
69 @param login is the login of the POP3 account.
70
71 @param password is the password of the POP3 account.
72
73 @param cached if this value is != 0, a persistant cache will be
74 stored on local system.
75
76 @param cache_directory is the location of the cache
77
78 @param flags_directory is the location of the flags
79*/
80
81int nntp_mailstorage_init(struct mailstorage * storage,
82 char * nntp_servername, uint16_t nntp_port,
83 char * nntp_command,
84 int nntp_connection_type, int nntp_auth_type,
85 char * nntp_login, char * nntp_password,
86 int nntp_cached, char * nntp_cache_directory,
87 char * nntp_flags_directory);
88
89#ifdef __cplusplus
90}
91#endif
92
93#endif
diff --git a/kmicromail/libetpan/include/libetpan/pop3driver.h b/kmicromail/libetpan/include/libetpan/pop3driver.h
new file mode 100644
index 0000000..2df94db
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/pop3driver.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef POP3DRIVER_H
37
38#define POP3DRIVER_H
39
40#include <libetpan/pop3driver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailsession_driver * pop3_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/pop3driver_cached.h b/kmicromail/libetpan/include/libetpan/pop3driver_cached.h
new file mode 100644
index 0000000..953e699
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/pop3driver_cached.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef POP3DRIVER_CACHED_H
37
38#define POP3DRIVER_CACHED_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/pop3driver_types.h>
45
46extern mailsession_driver * pop3_cached_session_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/pop3driver_cached_message.h b/kmicromail/libetpan/include/libetpan/pop3driver_cached_message.h
new file mode 100644
index 0000000..d03f8e5
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/pop3driver_cached_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef POP3DRIVER_CACHED_MESSAGE_H
37
38#define POP3DRIVER_CACHED_MESSAGE_H
39
40#include <libetpan/pop3driver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * pop3_cached_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/pop3driver_message.h b/kmicromail/libetpan/include/libetpan/pop3driver_message.h
new file mode 100644
index 0000000..6281a39
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/pop3driver_message.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef POP3DRIVER_MESSAGE_H
37
38#define POP3DRIVER_MESSAGE_H
39
40#include <libetpan/pop3driver_types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46extern mailmessage_driver * pop3_message_driver;
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/include/libetpan/pop3driver_types.h b/kmicromail/libetpan/include/libetpan/pop3driver_types.h
new file mode 100644
index 0000000..73286d8
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/pop3driver_types.h
@@ -0,0 +1,153 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef POP3DRIVER_TYPES_H
37
38#define POP3DRIVER_TYPES_H
39
40#include <libetpan/libetpan-config.h>
41
42#include <libetpan/maildriver_types.h>
43#include <libetpan/mailpop3.h>
44#include <libetpan/maildriver_types.h>
45#include <libetpan/chash.h>
46#include <libetpan/mailstorage_types.h>
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52/* POP3 driver for session */
53
54enum {
55 POP3DRIVER_SET_AUTH_TYPE = 1,
56};
57
58enum {
59 POP3DRIVER_AUTH_TYPE_PLAIN = 0,
60 POP3DRIVER_AUTH_TYPE_APOP,
61 POP3DRIVER_AUTH_TYPE_TRY_APOP,
62};
63
64struct pop3_session_state_data {
65 int pop3_auth_type;
66 mailpop3 * pop3_session;
67};
68
69/* cached POP3 driver for session */
70
71enum {
72 /* the mapping of the parameters should be the same as for pop3 */
73 POP3DRIVER_CACHED_SET_AUTH_TYPE = 1,
74 /* cache specific */
75 POP3DRIVER_CACHED_SET_CACHE_DIRECTORY,
76 POP3DRIVER_CACHED_SET_FLAGS_DIRECTORY,
77};
78
79struct pop3_cached_session_state_data {
80 mailsession * pop3_ancestor;
81 char pop3_cache_directory[PATH_MAX];
82 char pop3_flags_directory[PATH_MAX];
83 chash * pop3_flags_hash;
84 carray * pop3_flags_array;
85 struct mail_flags_store * pop3_flags_store;
86};
87
88/* pop3 storage */
89
90/*
91 pop3_mailstorage is the state data specific to the POP3 storage.
92
93 - servername this is the name of the POP3 server
94
95 - port is the port to connect to, on the server.
96 you give 0 to use the default port.
97
98 - connection_type is the type of socket layer to use.
99 The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
100 CONNECTION_TYPE_TRY_STARTTLS or CONNECTION_TYPE_TLS.
101
102 - auth_type is the authenticate mechanism to use.
103 The value can be POP3_AUTH_TYPE_PLAIN, POP3_AUTH_TYPE_APOP
104 or POP3_AUTH_TYPE_TRY_APOP. Other values are not yet implemented.
105
106 - login is the login of the POP3 account.
107
108 - password is the password of the POP3 account.
109
110 - cached if this value is != 0, a persistant cache will be
111 stored on local system.
112
113 - cache_directory is the location of the cache.
114
115 - flags_directory is the location of the flags.
116*/
117
118struct pop3_mailstorage {
119 char * pop3_servername;
120 uint16_t pop3_port;
121 char * pop3_command;
122 int pop3_connection_type;
123
124 int pop3_auth_type;
125 char * pop3_login;
126 char * pop3_password;
127
128 int pop3_cached;
129 char * pop3_cache_directory;
130 char * pop3_flags_directory;
131};
132
133/* this is the type of POP3 authentication */
134
135enum {
136 POP3_AUTH_TYPE_PLAIN, /* plain text authentication */
137 POP3_AUTH_TYPE_APOP, /* APOP authentication */
138 POP3_AUTH_TYPE_TRY_APOP, /* first, try APOP, if it fails,
139 try plain text */
140 POP3_AUTH_TYPE_SASL_ANONYMOUS, /* SASL anonymous */
141 POP3_AUTH_TYPE_SASL_CRAM_MD5, /* SASL CRAM MD5 */
142 POP3_AUTH_TYPE_SASL_KERBEROS_V4, /* SASL KERBEROS V4 */
143 POP3_AUTH_TYPE_SASL_PLAIN, /* SASL plain */
144 POP3_AUTH_TYPE_SASL_SCRAM_MD5, /* SASL SCRAM MD5 */
145 POP3_AUTH_TYPE_SASL_GSSAPI, /* SASL GSSAPI */
146 POP3_AUTH_TYPE_SASL_DIGEST_MD5, /* SASL digest MD5 */
147};
148
149#ifdef __cplusplus
150}
151#endif
152
153#endif
diff --git a/kmicromail/libetpan/include/libetpan/pop3storage.h b/kmicromail/libetpan/include/libetpan/pop3storage.h
new file mode 100644
index 0000000..c2118b6
--- a/dev/null
+++ b/kmicromail/libetpan/include/libetpan/pop3storage.h
@@ -0,0 +1,95 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef POP3STORAGE_H
37
38#define POP3STORAGE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/pop3driver_types.h>
45#include <libetpan/pop3driver.h>
46#include <libetpan/pop3driver_cached.h>
47
48/*
49 pop3_mailstorage_init is the constructor for a POP3 storage
50
51 @param storage this is the storage to initialize.
52
53 @param servername this is the name of the POP3 server
54
55 @param port is the port to connect to, on the server.
56 you give 0 to use the default port.
57
58 @param command the command used to connect to the server instead of
59 allowing normal TCP connections to be used.
60
61 @param connection_type is the type of socket layer to use.
62 The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
63 CONNECTION_TYPE_TRY_STARTTLS, CONNECTION_TYPE_TLS,
64 CONNECTION_TYPE_COMMAND, CONNECTION_TYPE_COMMAND_STARTTLS,
65 CONNECTION_TYPE_COMMAND_TRY_STARTTLS, CONNECTION_TYPE_COMMAND_TLS,.
66
67 @param auth_type is the authenticate mechanism to use.
68 The value can be POP3_AUTH_TYPE_PLAIN, POP3_AUTH_TYPE_APOP
69 or POP3_AUTH_TYPE_TRY_APOP. Other values are not yet implemented.
70
71 @param login is the login of the POP3 account.
72
73 @param password is the password of the POP3 account.
74
75 @param cached if this value is != 0, a persistant cache will be
76 stored on local system.
77
78 @param cache_directory is the location of the cache
79
80 @param flags_directory is the location of the flags
81*/
82
83int pop3_mailstorage_init(struct mailstorage * storage,
84 char * pop3_servername, uint16_t pop3_port,
85 char * pop3_command,
86 int pop3_connection_type, int pop3_auth_type,
87 char * pop3_login, char * pop3_password,
88 int pop3_cached, char * pop3_cache_directory,
89 char * pop3_flags_directory);
90
91#ifdef __cplusplus
92}
93#endif
94
95#endif
diff --git a/kmicromail/libetpan/libetpan-config.h b/kmicromail/libetpan/libetpan-config.h
new file mode 100644
index 0000000..20d1e62
--- a/dev/null
+++ b/kmicromail/libetpan/libetpan-config.h
@@ -0,0 +1,7 @@
1#ifndef LIBETPAN_CONFIG_H
2#define LIBETPAN_CONFIG_H
3#include <limits.h>
4#include <sys/param.h>
5#define MAIL_DIR_SEPARATOR '/'
6#define MAIL_DIR_SEPARATOR_S "/"
7#endif
diff --git a/kmicromail/libetpan/libetpanE.pro b/kmicromail/libetpan/libetpanE.pro
new file mode 100644
index 0000000..b7a9a16
--- a/dev/null
+++ b/kmicromail/libetpan/libetpanE.pro
@@ -0,0 +1,274 @@
1######################################################################
2# Automatically generated by qmake (1.07a) Thu Jul 1 00:54:03 2004
3######################################################################
4
5TEMPLATE = lib
6 TARGET = kmicrolibetpan
7
8OBJECTS_DIR = obj/$(PLATFORM)
9MOC_DIR = moc/$(PLATFORM)
10DESTDIR=$(QPEDIR)/lib
11
12DEPENDPATH += generic \
13 imap \
14 imf \
15 maildir \
16 mbox \
17 mh \
18 mime \
19 nntp \
20 pop3 \
21 smtp \
22 tests \
23 tools \
24 include/libetpan
25INCLUDEPATH += . \
26 generic \
27 include \
28 tools \
29 imf \
30 imap \
31 mime \
32 maildir \
33 mbox \
34 mh \
35 nntp \
36 pop3 \
37 smtp \
38 tests
39
40# Input
41HEADERS += generic/data_message_driver.h \
42 generic/generic_cache.h \
43 generic/generic_cache_types.h \
44 generic/imapdriver.h \
45 generic/imapdriver_cached.h \
46 generic/imapdriver_cached_message.h \
47 generic/imapdriver_message.h \
48 generic/imapdriver_tools.h \
49 generic/imapdriver_types.h \
50 generic/imapstorage.h \
51 generic/imfcache.h \
52 generic/libetpan.h \
53 generic/libetpan_version.h \
54 generic/maildirdriver.h \
55 generic/maildirdriver_cached.h \
56 generic/maildirdriver_cached_message.h \
57 generic/maildirdriver_message.h \
58 generic/maildirdriver_tools.h \
59 generic/maildirdriver_types.h \
60 generic/maildirstorage.h \
61 generic/maildriver.h \
62 generic/maildriver_errors.h \
63 generic/maildriver_tools.h \
64 generic/maildriver_types.h \
65 generic/maildriver_types_helper.h \
66 generic/mailfolder.h \
67 generic/mailmessage.h \
68 generic/mailmessage_tools.h \
69 generic/mailmessage_types.h \
70 generic/mailstorage.h \
71 generic/mailstorage_tools.h \
72 generic/mailstorage_types.h \
73 generic/mailthread.h \
74 generic/mailthread_types.h \
75 generic/mboxdriver.h \
76 generic/mboxdriver_cached.h \
77 generic/mboxdriver_cached_message.h \
78 generic/mboxdriver_message.h \
79 generic/mboxdriver_tools.h \
80 generic/mboxdriver_types.h \
81 generic/mboxstorage.h \
82 generic/mhdriver.h \
83 generic/mhdriver_cached.h \
84 generic/mhdriver_cached_message.h \
85 generic/mhdriver_message.h \
86 generic/mhdriver_tools.h \
87 generic/mhdriver_types.h \
88 generic/mhstorage.h \
89 generic/mime_message_driver.h \
90 generic/nntpdriver.h \
91 generic/nntpdriver_cached.h \
92 generic/nntpdriver_cached_message.h \
93 generic/nntpdriver_message.h \
94 generic/nntpdriver_tools.h \
95 generic/nntpdriver_types.h \
96 generic/nntpstorage.h \
97 generic/pop3driver.h \
98 generic/pop3driver_cached.h \
99 generic/pop3driver_cached_message.h \
100 generic/pop3driver_message.h \
101 generic/pop3driver_tools.h \
102 generic/pop3driver_types.h \
103 generic/pop3storage.h \
104 imap/mailimap.h \
105 imap/mailimap_helper.h \
106 imap/mailimap_keywords.h \
107 imap/mailimap_parser.h \
108 imap/mailimap_print.h \
109 imap/mailimap_sender.h \
110 imap/mailimap_socket.h \
111 imap/mailimap_ssl.h \
112 imap/mailimap_types.h \
113 imap/mailimap_types_helper.h \
114 imf/mailimf.h \
115 imf/mailimf_types.h \
116 imf/mailimf_types_helper.h \
117 imf/mailimf_write.h \
118 maildir/maildir.h \
119 maildir/maildir_types.h \
120 mbox/mailmbox.h \
121 mbox/mailmbox_parse.h \
122 mbox/mailmbox_types.h \
123 mh/mailmh.h \
124 mime/mailmime.h \
125 mime/mailmime_content.h \
126 mime/mailmime_decode.h \
127 mime/mailmime_disposition.h \
128 mime/mailmime_types.h \
129 mime/mailmime_types_helper.h \
130 mime/mailmime_write.h \
131 nntp/newsnntp.h \
132 nntp/newsnntp_socket.h \
133 nntp/newsnntp_ssl.h \
134 nntp/newsnntp_types.h \
135 pop3/mailpop3.h \
136 pop3/mailpop3_helper.h \
137 pop3/mailpop3_socket.h \
138 pop3/mailpop3_ssl.h \
139 pop3/mailpop3_types.h \
140 smtp/mailsmtp.h \
141 smtp/mailsmtp_helper.h \
142 smtp/mailsmtp_socket.h \
143 smtp/mailsmtp_ssl.h \
144 smtp/mailsmtp_types.h \
145 tools/base64.h \
146 tools/carray.h \
147 tools/charconv.h \
148 tools/chash.h \
149 tools/cinthash.h \
150 tools/clist.h \
151 tools/connect.h \
152 tools/hmac-md5.h \
153 tools/mail.h \
154 tools/mail_cache_db.h \
155 tools/mail_cache_db_types.h \
156 tools/maillock.h \
157 tools/mailstream.h \
158 tools/mailstream_helper.h \
159 tools/mailstream_low.h \
160 tools/mailstream_socket.h \
161 tools/mailstream_ssl.h \
162 tools/mailstream_types.h \
163 tools/mapping.h \
164 tools/md5.h \
165 tools/md5global.h \
166 tools/mmapstring.h \
167
168SOURCES += generic/data_message_driver.c \
169 generic/generic_cache.c \
170 generic/imapdriver.c \
171 generic/imapdriver_cached.c \
172 generic/imapdriver_cached_message.c \
173 generic/imapdriver_message.c \
174 generic/imapdriver_tools.c \
175 generic/imapstorage.c \
176 generic/imfcache.c \
177 generic/libetpan_version.c \
178 generic/maildirdriver.c \
179 generic/maildirdriver_cached.c \
180 generic/maildirdriver_cached_message.c \
181 generic/maildirdriver_message.c \
182 generic/maildirdriver_tools.c \
183 generic/maildirstorage.c \
184 generic/maildriver.c \
185 generic/maildriver_tools.c \
186 generic/maildriver_types.c \
187 generic/maildriver_types_helper.c \
188 generic/mailfolder.c \
189 generic/mailmessage.c \
190 generic/mailmessage_tools.c \
191 generic/mailmessage_types.c \
192 generic/mailstorage.c \
193 generic/mailstorage_tools.c \
194 generic/mailthread.c \
195 generic/mailthread_types.c \
196 generic/mboxdriver.c \
197 generic/mboxdriver_cached.c \
198 generic/mboxdriver_cached_message.c \
199 generic/mboxdriver_message.c \
200 generic/mboxdriver_tools.c \
201 generic/mboxstorage.c \
202 generic/mhdriver.c \
203 generic/mhdriver_cached.c \
204 generic/mhdriver_cached_message.c \
205 generic/mhdriver_message.c \
206 generic/mhdriver_tools.c \
207 generic/mhstorage.c \
208 generic/mime_message_driver.c \
209 generic/nntpdriver.c \
210 generic/nntpdriver_cached.c \
211 generic/nntpdriver_cached_message.c \
212 generic/nntpdriver_message.c \
213 generic/nntpdriver_tools.c \
214 generic/nntpstorage.c \
215 generic/pop3driver.c \
216 generic/pop3driver_cached.c \
217 generic/pop3driver_cached_message.c \
218 generic/pop3driver_message.c \
219 generic/pop3driver_tools.c \
220 generic/pop3storage.c \
221 imap/mailimap.c \
222 imap/mailimap_helper.c \
223 imap/mailimap_keywords.c \
224 imap/mailimap_parser.c \
225 imap/mailimap_print.c \
226 imap/mailimap_sender.c \
227 imap/mailimap_socket.c \
228 imap/mailimap_ssl.c \
229 imap/mailimap_types.c \
230 imap/mailimap_types_helper.c \
231 imf/mailimf.c \
232 imf/mailimf_types.c \
233 imf/mailimf_types_helper.c \
234 imf/mailimf_write.c \
235 maildir/maildir.c \
236 mbox/mailmbox.c \
237 mbox/mailmbox_parse.c \
238 mbox/mailmbox_types.c \
239 mh/mailmh.c \
240 mime/mailmime.c \
241 mime/mailmime_content.c \
242 mime/mailmime_decode.c \
243 mime/mailmime_disposition.c \
244 mime/mailmime_types.c \
245 mime/mailmime_types_helper.c \
246 mime/mailmime_write.c \
247 nntp/newsnntp.c \
248 nntp/newsnntp_socket.c \
249 nntp/newsnntp_ssl.c \
250 pop3/mailpop3.c \
251 pop3/mailpop3_helper.c \
252 pop3/mailpop3_socket.c \
253 pop3/mailpop3_ssl.c \
254 smtp/mailsmtp.c \
255 smtp/mailsmtp_helper.c \
256 smtp/mailsmtp_socket.c \
257 smtp/mailsmtp_ssl.c \
258 tools/base64.c \
259 tools/carray.c \
260 tools/charconv.c \
261 tools/chash.c \
262 tools/cinthash.c \
263 tools/clist.c \
264 tools/connect.c \
265 tools/mail_cache_db.c \
266 tools/maillock.c \
267 tools/mailstream.c \
268 tools/mailstream_helper.c \
269 tools/mailstream_low.c \
270 tools/mailstream_socket.c \
271 tools/mailstream_ssl.c \
272 tools/mapping.c \
273 tools/md5.c \
274 tools/mmapstring.c
diff --git a/kmicromail/libetpan/maildir/.libs/libmaildir.a b/kmicromail/libetpan/maildir/.libs/libmaildir.a
new file mode 100644
index 0000000..9eaf93e
--- a/dev/null
+++ b/kmicromail/libetpan/maildir/.libs/libmaildir.a
Binary files differ
diff --git a/kmicromail/libetpan/maildir/maildir.c b/kmicromail/libetpan/maildir/maildir.c
new file mode 100644
index 0000000..320ef81
--- a/dev/null
+++ b/kmicromail/libetpan/maildir/maildir.c
@@ -0,0 +1,710 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "maildir.h"
37
38#include <string.h>
39#include <stdlib.h>
40#include <stdio.h>
41#include <unistd.h>
42#include <sys/types.h>
43#include <dirent.h>
44#include <time.h>
45#include <sys/stat.h>
46#include <sys/mman.h>
47
48#ifdef LIBETPAN_SYSTEM_BASENAME
49#include <libgen.h>
50#endif
51
52/*
53 We suppose the maildir mailbox remains on one unique filesystem.
54*/
55
56struct maildir * maildir_new(const char * path)
57{
58 struct maildir * md;
59
60 md = malloc(sizeof(* md));
61 if (md == NULL)
62 goto err;
63
64 md->mdir_counter = 0;
65 md->mdir_mtime_new = (time_t) -1;
66 md->mdir_mtime_cur = (time_t) -1;
67
68 md->mdir_pid = getpid();
69 gethostname(md->mdir_hostname, sizeof(md->mdir_hostname));
70 strncpy(md->mdir_path, path, sizeof(md->mdir_path));
71 md->mdir_path[PATH_MAX - 1] = '\0';
72
73 md->mdir_msg_list = carray_new(128);
74 if (md->mdir_msg_list == NULL)
75 goto free;
76
77 md->mdir_msg_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYNONE);
78 if (md->mdir_msg_hash == NULL)
79 goto free_msg_list;
80
81 return md;
82
83 free_msg_list:
84 carray_free(md->mdir_msg_list);
85 free:
86 free(md);
87 err:
88 return NULL;
89}
90
91static void maildir_flush(struct maildir * md, int msg_new);
92
93void maildir_free(struct maildir * md)
94{
95 maildir_flush(md, 0);
96 maildir_flush(md, 1);
97 chash_free(md->mdir_msg_hash);
98 carray_free(md->mdir_msg_list);
99 free(md);
100}
101
102#define MAX_TRY_ALLOC 32
103
104static char * maildir_get_new_message_filename(struct maildir * md,
105 char * tmpfile)
106{
107 char filename[PATH_MAX];
108 char basename[PATH_MAX];
109 int k;
110 time_t now;
111
112 now = time(NULL);
113 k = 0;
114 while (k < MAX_TRY_ALLOC) {
115 snprintf(basename, sizeof(basename), "%lu.%u_%u.%s",
116 (unsigned long) now, md->mdir_pid, md->mdir_counter, md->mdir_hostname);
117 snprintf(filename, sizeof(filename), "%s/tmp/%s",
118 md->mdir_path, basename);
119
120 if (link(tmpfile, filename) == 0) {
121 char * dup_filename;
122
123 dup_filename = strdup(filename);
124 if (dup_filename == NULL) {
125 unlink(filename);
126 return NULL;
127 }
128
129 unlink(tmpfile);
130 md->mdir_counter ++;
131
132 return dup_filename;
133 }
134
135 md->mdir_counter ++;
136 k ++;
137 }
138
139 return NULL;
140}
141
142
143static void msg_free(struct maildir_msg * msg)
144{
145 free(msg->msg_uid);
146 free(msg->msg_filename);
147 free(msg);
148}
149
150/*
151 msg_new()
152
153 filename is given without path
154*/
155
156static struct maildir_msg * msg_new(char * filename, int new_msg)
157{
158 struct maildir_msg * msg;
159 char * p;
160 int flags;
161 size_t uid_len;
162 char * begin_uid;
163
164 /* name of file : xxx-xxx_xxx-xxx:2,SRFT */
165
166 msg = malloc(sizeof(* msg));
167 if (msg == NULL)
168 goto err;
169
170 msg->msg_filename = strdup(filename);
171 if (msg->msg_filename == NULL)
172 goto free;
173
174 begin_uid = filename;
175
176 uid_len = strlen(begin_uid);
177
178 flags = 0;
179 p = strstr(filename, ":2,");
180 if (p != NULL) {
181 uid_len = p - begin_uid;
182
183 p += 3;
184
185 /* parse flags */
186 while (* p != '\0') {
187 switch (* p) {
188 case 'S':
189 flags |= MAILDIR_FLAG_SEEN;
190 break;
191 case 'R':
192 flags |= MAILDIR_FLAG_REPLIED;
193 break;
194 case 'F':
195 flags |= MAILDIR_FLAG_FLAGGED;
196 break;
197 case 'T':
198 flags |= MAILDIR_FLAG_TRASHED;
199 break;
200 }
201 p ++;
202 }
203 }
204
205 if (new_msg)
206 flags |= MAILDIR_FLAG_NEW;
207
208 msg->msg_flags = flags;
209
210 msg->msg_uid = malloc(uid_len + 1);
211 if (msg->msg_uid == NULL)
212 goto free_filename;
213
214 strncpy(msg->msg_uid, begin_uid, uid_len);
215 msg->msg_uid[uid_len] = '\0';
216
217 return msg;
218
219 free_filename:
220 free(msg->msg_filename);
221 free:
222 free(msg);
223 err:
224 return NULL;
225}
226
227static void maildir_flush(struct maildir * md, int msg_new)
228{
229 unsigned int i;
230
231 i = 0;
232 while (i < carray_count(md->mdir_msg_list)) {
233 struct maildir_msg * msg;
234 int delete;
235
236 msg = carray_get(md->mdir_msg_list, i);
237
238 if (msg_new) {
239 delete = 0;
240 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
241 delete = 1;
242 }
243 else {
244 delete = 1;
245 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
246 delete = 0;
247 }
248
249 if (delete) {
250 chashdatum key;
251
252 key.data = msg->msg_uid;
253 key.len = strlen(msg->msg_uid);
254 chash_delete(md->mdir_msg_hash, &key, NULL);
255
256 carray_delete(md->mdir_msg_list, i);
257 msg_free(msg);
258 }
259 else {
260 i ++;
261 }
262 }
263}
264
265static int add_message(struct maildir * md,
266 char * filename, int is_new)
267{
268 struct maildir_msg * msg;
269 chashdatum key;
270 chashdatum value;
271 unsigned int i;
272 int res;
273 int r;
274
275 msg = msg_new(filename, is_new);
276 if (msg == NULL) {
277 res = MAILDIR_ERROR_MEMORY;
278 goto err;
279 }
280
281 r = carray_add(md->mdir_msg_list, msg, &i);
282 if (r < 0) {
283 res = MAILDIR_ERROR_MEMORY;
284 goto free_msg;
285 }
286
287 key.data = msg->msg_uid;
288 key.len = strlen(msg->msg_uid);
289 value.data = msg;
290 value.len = 0;
291
292 r = chash_set(md->mdir_msg_hash, &key, &value, NULL);
293 if (r < 0) {
294 res = MAILDIR_ERROR_MEMORY;
295 goto delete;
296 }
297
298 return MAILDIR_NO_ERROR;
299
300 delete:
301 carray_delete(md->mdir_msg_list, i);
302 free_msg:
303 msg_free(msg);
304 err:
305 return res;
306}
307
308static int add_directory(struct maildir * md, char * path, int is_new)
309{
310 DIR * d;
311 struct dirent * entry;
312 int res;
313 int r;
314 char filename[PATH_MAX];
315
316 d = opendir(path);
317 if (d == NULL) {
318 res = MAILDIR_ERROR_DIRECTORY;
319 goto err;
320 }
321
322 while ((entry = readdir(d)) != NULL) {
323 struct stat stat_info;
324
325 snprintf(filename, sizeof(filename), "%s/%s", path, entry->d_name);
326 r = stat(filename, &stat_info);
327 if (r < 0)
328 continue;
329
330 if (S_ISDIR(stat_info.st_mode))
331 continue;
332
333 r = add_message(md, entry->d_name, is_new);
334 if (r != MAILDIR_NO_ERROR) {
335 /* ignore errors */
336 }
337 }
338
339 closedir(d);
340
341 return MAILDIR_NO_ERROR;
342
343 err:
344 return res;
345}
346
347int maildir_update(struct maildir * md)
348{
349 struct stat stat_info;
350 char path_new[PATH_MAX];
351 char path_cur[PATH_MAX];
352 int r;
353 int res;
354
355 snprintf(path_new, sizeof(path_new), "%s/new", md->mdir_path);
356 snprintf(path_cur, sizeof(path_cur), "%s/cur", md->mdir_path);
357
358 /* did new/ changed ? */
359
360 r = stat(path_new, &stat_info);
361 if (r < 0) {
362 res = MAILDIR_ERROR_DIRECTORY;
363 goto free;
364 }
365
366 if (md->mdir_mtime_new != stat_info.st_mtime) {
367 md->mdir_mtime_new = stat_info.st_mtime;
368
369 maildir_flush(md, 1);
370
371 /* messages in new */
372 r = add_directory(md, path_new, 1);
373 if (r != MAILDIR_NO_ERROR) {
374 res = r;
375 goto free;
376 }
377 }
378
379 /* did cur/ changed ? */
380
381 r = stat(path_cur, &stat_info);
382 if (r < 0) {
383 res = MAILDIR_ERROR_DIRECTORY;
384 goto free;
385 }
386
387 if (md->mdir_mtime_cur != stat_info.st_mtime) {
388 md->mdir_mtime_cur = stat_info.st_mtime;
389
390 maildir_flush(md, 0);
391
392 /* messages in cur */
393 r = add_directory(md, path_cur, 0);
394 if (r != MAILDIR_NO_ERROR) {
395 res = r;
396 goto free;
397 }
398 }
399
400 return MAILDIR_NO_ERROR;
401
402 free:
403 maildir_flush(md, 0);
404 maildir_flush(md, 1);
405 md->mdir_mtime_cur = (time_t) -1;
406 md->mdir_mtime_new = (time_t) -1;
407 return res;
408}
409
410#ifndef LIBETPAN_SYSTEM_BASENAME
411static char * libetpan_basename(char * filename)
412{
413 char * next;
414 char * p;
415
416 p = filename;
417 next = strchr(p, '/');
418
419 while (next != NULL) {
420 p = next;
421 next = strchr(p + 1, '/');
422 }
423
424 if (p == filename)
425 return filename;
426 else
427 return p + 1;
428}
429#else
430#define libetpan_basename(a) basename(a)
431#endif
432
433int maildir_message_add(struct maildir * md,
434 const char * message, size_t size)
435{
436 char path_new[PATH_MAX];
437 char tmpname[PATH_MAX];
438 int fd;
439 int r;
440 char * mapping;
441 char * delivery_tmp_name;
442 char * delivery_tmp_basename;
443 char delivery_new_name[PATH_MAX];
444 char * delivery_new_basename;
445 int res;
446 struct stat stat_info;
447
448 r = maildir_update(md);
449 if (r != MAILDIR_NO_ERROR) {
450 res = r;
451 goto err;
452 }
453
454 /* write to tmp/ with a classic temporary file */
455
456 snprintf(tmpname, sizeof(tmpname), "%s/tmp/etpan-maildir-XXXXXX", md->mdir_path);
457 fd = mkstemp(tmpname);
458 if (fd < 0) {
459 res = MAILDIR_ERROR_FILE;
460 goto err;
461 }
462
463 r = ftruncate(fd, size);
464 if (r < 0) {
465 res = MAILDIR_ERROR_FILE;
466 goto close;
467 }
468
469 mapping = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
470 if (mapping == MAP_FAILED) {
471 res = MAILDIR_ERROR_FILE;
472 goto close;
473 }
474
475 memcpy(mapping, message, size);
476
477 msync(mapping, size, MS_SYNC);
478 munmap(mapping, size);
479
480 close(fd);
481
482 /* write to tmp/ with maildir standard name */
483
484 delivery_tmp_name = maildir_get_new_message_filename(md, tmpname);
485 if (delivery_tmp_name == NULL) {
486 res = MAILDIR_ERROR_FILE;
487 goto unlink;
488 }
489
490 /* write to new/ with maildir standard name */
491
492 strncpy(tmpname, delivery_tmp_name, sizeof(tmpname));
493 tmpname[sizeof(tmpname) - 1] = '\0';
494
495 delivery_tmp_basename = libetpan_basename(tmpname);
496
497 snprintf(delivery_new_name, sizeof(delivery_new_name), "%s/new/%s",
498 md->mdir_path, delivery_tmp_basename);
499
500 r = link(delivery_tmp_name, delivery_new_name);
501 if (r < 0) {
502 res = MAILDIR_ERROR_FILE;
503 goto unlink_tmp;
504 }
505
506 snprintf(path_new, sizeof(path_new), "%s/new", md->mdir_path);
507 r = stat(path_new, &stat_info);
508 if (r < 0) {
509 unlink(delivery_new_name);
510 res = MAILDIR_ERROR_FILE;
511 goto unlink_tmp;
512 }
513
514 md->mdir_mtime_new = stat_info.st_mtime;
515
516 delivery_new_basename = libetpan_basename(delivery_new_name);
517
518 r = add_message(md, delivery_new_basename, 1);
519 if (r != MAILDIR_NO_ERROR) {
520 unlink(delivery_new_name);
521 res = MAILDIR_ERROR_FILE;
522 goto unlink_tmp;
523 }
524
525 unlink(delivery_tmp_name);
526 free(delivery_tmp_name);
527
528 return MAILDIR_NO_ERROR;
529
530 unlink_tmp:
531 unlink(delivery_tmp_name);
532 free(delivery_tmp_name);
533 goto err;
534 close:
535 close(fd);
536 unlink:
537 unlink(tmpname);
538 err:
539 return res;
540}
541
542int maildir_message_add_file(struct maildir * md, int fd)
543{
544 char * message;
545 struct stat buf;
546 int r;
547
548 if (fstat(fd, &buf) == -1)
549 return MAILDIR_ERROR_FILE;
550
551 message = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
552 if (message == MAP_FAILED)
553 return MAILDIR_ERROR_FILE;
554
555 r = maildir_message_add(md, message, buf.st_size);
556
557 munmap(message, buf.st_size);
558
559 return r;
560}
561
562char * maildir_message_get(struct maildir * md, const char * uid)
563{
564 chashdatum key;
565 chashdatum value;
566 char filename[PATH_MAX];
567 char * dup_filename;
568 struct maildir_msg * msg;
569 char * dir;
570 int r;
571
572 key.data = (void *) uid;
573 key.len = strlen(uid);
574 r = chash_get(md->mdir_msg_hash, &key, &value);
575 if (r < 0)
576 return NULL;
577
578 msg = value.data;
579 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
580 dir = "new";
581 else
582 dir = "cur";
583
584 snprintf(filename, sizeof(filename), "%s/%s/%s",
585 md->mdir_path, dir, msg->msg_filename);
586
587 dup_filename = strdup(filename);
588 if (dup_filename == NULL)
589 return NULL;
590
591 return dup_filename;
592}
593
594int maildir_message_remove(struct maildir * md, const char * uid)
595{
596 chashdatum key;
597 chashdatum value;
598 char filename[PATH_MAX];
599 struct maildir_msg * msg;
600 char * dir;
601 int r;
602 int res;
603
604 key.data = (void *) uid;
605 key.len = strlen(uid);
606 r = chash_get(md->mdir_msg_hash, &key, &value);
607 if (r < 0) {
608 res = MAILDIR_ERROR_NOT_FOUND;
609 goto err;
610 }
611
612 msg = value.data;
613 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
614 dir = "new";
615 else
616 dir = "cur";
617
618 snprintf(filename, sizeof(filename), "%s/%s/%s",
619 md->mdir_path, dir, msg->msg_filename);
620
621 r = unlink(filename);
622 if (r < 0) {
623 res = MAILDIR_ERROR_FILE;
624 goto err;
625 }
626
627 return MAILDIR_NO_ERROR;
628
629 err:
630 return res;
631}
632
633int maildir_message_change_flags(struct maildir * md,
634 const char * uid, int new_flags)
635{
636 chashdatum key;
637 chashdatum value;
638 char filename[PATH_MAX];
639 struct maildir_msg * msg;
640 char * dir;
641 int r;
642 char new_filename[PATH_MAX];
643 char flag_str[5];
644 size_t i;
645 int res;
646
647 key.data = (void *) uid;
648 key.len = strlen(uid);
649 r = chash_get(md->mdir_msg_hash, &key, &value);
650 if (r < 0) {
651 res = MAILDIR_ERROR_NOT_FOUND;
652 goto err;
653 }
654
655 msg = value.data;
656 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
657 dir = "new";
658 else
659 dir = "cur";
660
661 snprintf(filename, sizeof(filename), "%s/%s/%s",
662 md->mdir_path, dir, msg->msg_filename);
663
664 if ((new_flags & MAILDIR_FLAG_NEW) != 0)
665 dir = "new";
666 else
667 dir = "cur";
668
669 i = 0;
670 if ((new_flags & MAILDIR_FLAG_SEEN) != 0) {
671 flag_str[i] = 'S';
672 i ++;
673 }
674 if ((new_flags & MAILDIR_FLAG_REPLIED) != 0) {
675 flag_str[i] = 'R';
676 i ++;
677 }
678 if ((new_flags & MAILDIR_FLAG_FLAGGED) != 0) {
679 flag_str[i] = 'F';
680 i ++;
681 }
682 if ((new_flags & MAILDIR_FLAG_TRASHED) != 0) {
683 flag_str[i] = 'T';
684 i ++;
685 }
686 flag_str[i] = 0;
687
688 if (flag_str[0] == '\0')
689 snprintf(new_filename, sizeof(new_filename), "%s/%s/%s",
690 md->mdir_path, dir, msg->msg_uid);
691 else
692 snprintf(new_filename, sizeof(new_filename), "%s/%s/%s:2,%s",
693 md->mdir_path, dir, msg->msg_uid, flag_str);
694
695 if (strcmp(filename, new_filename) == 0)
696 return MAILDIR_NO_ERROR;
697
698 r = link(filename, new_filename);
699 if (r < 0) {
700 res = MAILDIR_ERROR_FILE;
701 goto err;
702 }
703
704 unlink(filename);
705
706 return MAILDIR_NO_ERROR;
707
708 err:
709 return res;
710}
diff --git a/kmicromail/libetpan/maildir/maildir.h b/kmicromail/libetpan/maildir/maildir.h
new file mode 100644
index 0000000..b782484
--- a/dev/null
+++ b/kmicromail/libetpan/maildir/maildir.h
@@ -0,0 +1,60 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIR_H
37
38#define MAILDIR_H
39
40#include <libetpan/maildir_types.h>
41
42struct maildir * maildir_new(const char * path);
43
44void maildir_free(struct maildir * md);
45
46int maildir_update(struct maildir * md);
47
48int maildir_message_add(struct maildir * md,
49 const char * message, size_t size);
50
51int maildir_message_add_file(struct maildir * md, int fd);
52
53char * maildir_message_get(struct maildir * md, const char * uid);
54
55int maildir_message_remove(struct maildir * md, const char * uid);
56
57int maildir_message_change_flags(struct maildir * md,
58 const char * uid, int new_flags);
59
60#endif
diff --git a/kmicromail/libetpan/maildir/maildir_types.h b/kmicromail/libetpan/maildir/maildir_types.h
new file mode 100644
index 0000000..c7e368e
--- a/dev/null
+++ b/kmicromail/libetpan/maildir/maildir_types.h
@@ -0,0 +1,90 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001 - 2003 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILDIR_TYPES_H
37
38#define MAILDIR_TYPES_H
39
40#include <sys/types.h>
41#include <unistd.h>
42#include <libetpan/chash.h>
43#include <libetpan/carray.h>
44#include <inttypes.h>
45
46#include <libetpan/libetpan-config.h>
47
48#define LIBETPAN_MAILDIR
49
50enum {
51 MAILDIR_NO_ERROR = 0,
52 MAILDIR_ERROR_CREATE,
53 MAILDIR_ERROR_DIRECTORY,
54 MAILDIR_ERROR_MEMORY,
55 MAILDIR_ERROR_FILE,
56 MAILDIR_ERROR_NOT_FOUND,
57};
58
59#define MAILDIR_FLAG_NEW (1 << 0)
60#define MAILDIR_FLAG_SEEN (1 << 1)
61#define MAILDIR_FLAG_REPLIED (1 << 2)
62#define MAILDIR_FLAG_FLAGGED (1 << 3)
63#define MAILDIR_FLAG_TRASHED (1 << 4)
64
65struct maildir_msg {
66 char * msg_uid;
67 char * msg_filename;
68 int msg_flags;
69};
70
71/*
72 work around for missing #define HOST_NAME_MAX in Linux
73*/
74
75#ifndef HOST_NAME_MAX
76#define HOST_NAME_MAX 255
77#endif
78
79struct maildir {
80 pid_t mdir_pid;
81 char mdir_hostname[HOST_NAME_MAX];
82 char mdir_path[PATH_MAX];
83 uint32_t mdir_counter;
84 time_t mdir_mtime_new;
85 time_t mdir_mtime_cur;
86 carray * mdir_msg_list;
87 chash * mdir_msg_hash;
88};
89
90#endif
diff --git a/kmicromail/libetpan/mbox/.libs/libmailmbox.a b/kmicromail/libetpan/mbox/.libs/libmailmbox.a
new file mode 100644
index 0000000..7b92e2d
--- a/dev/null
+++ b/kmicromail/libetpan/mbox/.libs/libmailmbox.a
Binary files differ
diff --git a/kmicromail/libetpan/mbox/TODO b/kmicromail/libetpan/mbox/TODO
new file mode 100644
index 0000000..e69de29
--- a/dev/null
+++ b/kmicromail/libetpan/mbox/TODO
diff --git a/kmicromail/libetpan/mbox/mailmbox.c b/kmicromail/libetpan/mbox/mailmbox.c
new file mode 100644
index 0000000..280c313
--- a/dev/null
+++ b/kmicromail/libetpan/mbox/mailmbox.c
@@ -0,0 +1,1424 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailmbox.h"
37
38#include <sys/file.h>
39#include <sys/stat.h>
40#include <unistd.h>
41#include <sys/mman.h>
42#include <fcntl.h>
43#include <time.h>
44#include <sys/types.h>
45#include <unistd.h>
46
47#include <string.h>
48#include <ctype.h>
49#include <stdlib.h>
50#include <stdio.h>
51
52#include "libetpan-config.h"
53
54#include "mmapstring.h"
55#include "mailmbox_parse.h"
56#include "maillock.h"
57
58/*
59 http://www.qmail.org/qmail-manual-html/man5/mbox.html
60 RFC 2076
61*/
62
63#define TMPDIR "/tmp"
64
65/* mbox is a file with a corresponding filename */
66
67#define UID_HEADER "X-LibEtPan-UID:"
68
69#ifndef TRUE
70#define TRUE 1
71#endif
72
73#ifndef FALSE
74#define FALSE 0
75#endif
76
77int mailmbox_write_lock(struct mailmbox_folder * folder)
78{
79 int r;
80
81 if (folder->mb_read_only)
82 return MAILMBOX_ERROR_READONLY;
83
84 r = maillock_write_lock(folder->mb_filename, folder->mb_fd);
85 if (r == 0)
86 return MAILMBOX_NO_ERROR;
87 else
88 return MAILMBOX_ERROR_FILE;
89}
90
91int mailmbox_write_unlock(struct mailmbox_folder * folder)
92{
93 int r;
94
95 r = maillock_write_unlock(folder->mb_filename, folder->mb_fd);
96 if (r == 0)
97 return MAILMBOX_NO_ERROR;
98 else
99 return MAILMBOX_ERROR_FILE;
100}
101
102int mailmbox_read_lock(struct mailmbox_folder * folder)
103{
104 int r;
105
106 r = maillock_read_lock(folder->mb_filename, folder->mb_fd);
107 if (r == 0)
108 return MAILMBOX_NO_ERROR;
109 else
110 return MAILMBOX_ERROR_FILE;
111}
112
113int mailmbox_read_unlock(struct mailmbox_folder * folder)
114{
115 int r;
116
117 r = maillock_read_unlock(folder->mb_filename, folder->mb_fd);
118 if (r == 0)
119 return MAILMBOX_NO_ERROR;
120 else
121 return MAILMBOX_ERROR_FILE;
122}
123
124
125/*
126 map the file into memory.
127 the file must be locked.
128*/
129
130int mailmbox_map(struct mailmbox_folder * folder)
131{
132 char * str;
133 struct stat buf;
134 int res;
135 int r;
136
137 r = stat(folder->mb_filename, &buf);
138 if (r < 0) {
139 res = MAILMBOX_ERROR_FILE;
140 goto err;
141 }
142
143 if (folder->mb_read_only)
144 str = (char *) mmap(0, buf.st_size, PROT_READ,
145 MAP_PRIVATE, folder->mb_fd, 0);
146 else
147 str = (char *) mmap(0, buf.st_size, PROT_READ | PROT_WRITE,
148 MAP_SHARED, folder->mb_fd, 0);
149 if (str == MAP_FAILED) {
150 res = MAILMBOX_ERROR_FILE;
151 goto err;
152 }
153
154 folder->mb_mapping = str;
155 folder->mb_mapping_size = buf.st_size;
156
157 return MAILMBOX_NO_ERROR;
158
159 err:
160 return res;
161}
162
163/*
164 unmap the file
165*/
166
167void mailmbox_unmap(struct mailmbox_folder * folder)
168{
169 munmap(folder->mb_mapping, folder->mb_mapping_size);
170 folder->mb_mapping = NULL;
171 folder->mb_mapping_size = 0;
172}
173
174void mailmbox_sync(struct mailmbox_folder * folder)
175{
176 msync(folder->mb_mapping, folder->mb_mapping_size, MS_SYNC);
177}
178
179void mailmbox_timestamp(struct mailmbox_folder * folder)
180{
181 int r;
182 struct stat buf;
183
184 r = stat(folder->mb_filename, &buf);
185 if (r < 0)
186 folder->mb_mtime = (time_t) -1;
187 else
188 folder->mb_mtime = buf.st_mtime;
189}
190
191/*
192 open the file
193*/
194
195int mailmbox_open(struct mailmbox_folder * folder)
196{
197 int fd;
198 int read_only;
199
200 if (!folder->mb_read_only) {
201 read_only = FALSE;
202 fd = open(folder->mb_filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
203 }
204
205 if (folder->mb_read_only || (fd < 0)) {
206 read_only = TRUE;
207 fd = open(folder->mb_filename, O_RDONLY);
208 if (fd < 0)
209 return MAILMBOX_ERROR_FILE_NOT_FOUND;
210 }
211
212 folder->mb_fd = fd;
213 folder->mb_read_only = read_only;
214
215 return MAILMBOX_NO_ERROR;
216}
217
218/*
219 close the file
220*/
221
222void mailmbox_close(struct mailmbox_folder * folder)
223{
224 close(folder->mb_fd);
225 folder->mb_fd = -1;
226}
227
228
229static int mailmbox_validate_lock(struct mailmbox_folder * folder,
230 int (* custom_lock)(struct mailmbox_folder *),
231 int (* custom_unlock)(struct mailmbox_folder *))
232{
233 struct stat buf;
234 int res;
235 int r;
236
237 r = stat(folder->mb_filename, &buf);
238 if (r < 0) {
239 buf.st_mtime = (time_t) -1;
240 }
241
242 if ((buf.st_mtime != folder->mb_mtime) ||
243 ((size_t) buf.st_size != folder->mb_mapping_size)) {
244 int r;
245
246 mailmbox_unmap(folder);
247 mailmbox_close(folder);
248
249 r = mailmbox_open(folder);
250 if (r != MAILMBOX_NO_ERROR) {
251 res = r;
252 goto err;
253 }
254
255 r = custom_lock(folder);
256 if (r != MAILMBOX_NO_ERROR) {
257 res = r;
258 goto err;
259 }
260
261 r = mailmbox_map(folder);
262 if (r != MAILMBOX_NO_ERROR) {
263 res = r;
264 goto err_unlock;
265 }
266
267 r = mailmbox_parse(folder);
268 if (r != MAILMBOX_NO_ERROR) {
269 res = r;
270 goto err_unlock;
271 }
272
273 folder->mb_mtime = buf.st_mtime;
274
275 return MAILMBOX_NO_ERROR;
276 }
277 else {
278 r = custom_lock(folder);
279 if (r != MAILMBOX_NO_ERROR) {
280 res = r;
281 goto err;
282 }
283 }
284
285 return MAILMBOX_NO_ERROR;
286
287 err_unlock:
288 custom_unlock(folder);
289 err:
290 return res;
291}
292
293
294int mailmbox_validate_write_lock(struct mailmbox_folder * folder)
295{
296 return mailmbox_validate_lock(folder,
297 mailmbox_write_lock,
298 mailmbox_write_unlock);
299}
300
301
302int mailmbox_validate_read_lock(struct mailmbox_folder * folder)
303{
304 return mailmbox_validate_lock(folder,
305 mailmbox_read_lock,
306 mailmbox_read_unlock);
307}
308
309
310/* ********************************************************************** */
311/* append messages */
312
313#define MAX_FROM_LINE_SIZE 256
314
315static inline size_t get_line(const char * line, size_t length,
316 const char ** pnext_line, size_t * pcount)
317{
318 size_t count;
319
320 count = 0;
321
322 while (1) {
323 if (length == 0)
324 break;
325
326 if (* line == '\r') {
327 line ++;
328
329 count ++;
330 length --;
331
332 if (length > 0) {
333 if (* line == '\n') {
334 line ++;
335
336 count ++;
337 length --;
338
339 break;
340 }
341 }
342 }
343 else if (* line == '\n') {
344 line ++;
345
346 count ++;
347 length --;
348
349 break;
350 }
351 else {
352 line ++;
353 length --;
354 count ++;
355 }
356 }
357
358 * pnext_line = line;
359 * pcount = count;
360
361 return count;
362}
363
364/*
365 TODO : should strip \r\n if any
366 see also in write_fixed_line
367*/
368
369static inline size_t get_fixed_line_size(const char * line, size_t length,
370 const char ** pnext_line, size_t * pcount,
371 size_t * pfixed_count)
372{
373 size_t count;
374 const char * next_line;
375 size_t fixed_count;
376
377 if (!get_line(line, length, &next_line, &count))
378 return 0;
379
380 fixed_count = count;
381 if (count >= 5) {
382 if (line[0] == 'F') {
383 if (strncmp(line, "From ", 5) == 0)
384 fixed_count ++;
385 }
386 }
387
388 * pnext_line = next_line;
389 * pcount = count;
390 * pfixed_count = fixed_count;
391
392 return count;
393}
394
395static size_t get_fixed_message_size(const char * message, size_t size,
396 uint32_t uid, int force_no_uid)
397{
398 size_t fixed_size;
399 size_t cur_token;
400 size_t left;
401 const char * next;
402 const char * cur;
403 int end;
404 int r;
405 uint32_t tmp_uid;
406
407 cur_token = 0;
408
409 fixed_size = 0;
410
411 /* headers */
412
413 end = FALSE;
414 while (!end) {
415 size_t begin;
416 int ignore;
417
418 ignore = FALSE;
419 begin = cur_token;
420 if (cur_token + strlen(UID_HEADER) <= size) {
421 if (message[cur_token] == 'X') {
422 if (strncasecmp(message + cur_token, UID_HEADER,
423 strlen(UID_HEADER)) == 0) {
424 ignore = TRUE;
425 }
426 }
427 }
428
429 r = mailimf_ignore_field_parse(message, size, &cur_token);
430 switch (r) {
431 case MAILIMF_NO_ERROR:
432 if (!ignore)
433 fixed_size += cur_token - begin;
434 break;
435 case MAILIMF_ERROR_PARSE:
436 default:
437 end = TRUE;
438 break;
439 }
440 }
441
442 if (!force_no_uid) {
443 /* UID header */
444
445 fixed_size += strlen(UID_HEADER " \r\n");
446
447 tmp_uid = uid;
448 while (tmp_uid >= 10) {
449 tmp_uid /= 10;
450 fixed_size ++;
451 }
452 fixed_size ++;
453 }
454
455 /* body */
456
457 left = size - cur_token;
458 next = message + cur_token;
459 while (left > 0) {
460 size_t count;
461 size_t fixed_count;
462
463 cur = next;
464
465 if (!get_fixed_line_size(cur, left, &next, &count, &fixed_count))
466 break;
467
468 fixed_size += fixed_count;
469 left -= count;
470 }
471
472 return fixed_size;
473}
474
475static inline char * write_fixed_line(char * str,
476 const char * line, size_t length,
477 const char ** pnext_line, size_t * pcount)
478{
479 size_t count;
480 const char * next_line;
481
482 if (!get_line(line, length, &next_line, &count))
483 return str;
484
485 if (count >= 5) {
486 if (line[0] == 'F') {
487 if (strncmp(line, "From ", 5) == 0) {
488 * str = '>';
489 str ++;
490 }
491 }
492 }
493
494 memcpy(str, line, count);
495
496 * pnext_line = next_line;
497 * pcount = count;
498 str += count;
499
500 return str;
501}
502
503static char * write_fixed_message(char * str,
504 const char * message, size_t size,
505 uint32_t uid, int force_no_uid)
506{
507 size_t fixed_size;
508 size_t cur_token;
509 size_t left;
510 int end;
511 int r;
512 const char * cur_src;
513 size_t numlen;
514
515 cur_token = 0;
516
517 fixed_size = 0;
518
519 /* headers */
520
521 end = FALSE;
522 while (!end) {
523 size_t begin;
524 int ignore;
525
526 ignore = FALSE;
527 begin = cur_token;
528 if (cur_token + strlen(UID_HEADER) <= size) {
529 if (message[cur_token] == 'X') {
530 if (strncasecmp(message + cur_token, UID_HEADER,
531 strlen(UID_HEADER)) == 0) {
532 ignore = TRUE;
533 }
534 }
535 }
536
537 r = mailimf_ignore_field_parse(message, size, &cur_token);
538 switch (r) {
539 case MAILIMF_NO_ERROR:
540 if (!ignore) {
541 memcpy(str, message + begin, cur_token - begin);
542 str += cur_token - begin;
543 }
544 break;
545 case MAILIMF_ERROR_PARSE:
546 default:
547 end = TRUE;
548 break;
549 }
550 }
551
552 if (!force_no_uid) {
553 /* UID header */
554
555 memcpy(str, UID_HEADER " ", strlen(UID_HEADER " "));
556 str += strlen(UID_HEADER " ");
557 numlen = snprintf(str, 20, "%i\r\n", uid);
558 str += numlen;
559 }
560
561 /* body */
562
563 cur_src = message + cur_token;
564 left = size - cur_token;
565 while (left > 0) {
566 size_t count;
567 const char * next;
568
569 str = write_fixed_line(str, cur_src, left, &next, &count);
570
571 cur_src = next;
572 left -= count;
573 }
574
575 return str;
576}
577
578#define DEFAULT_FROM_LINE "From - Wed Jun 30 21:49:08 1993\n"
579
580int
581mailmbox_append_message_list_no_lock(struct mailmbox_folder * folder,
582 carray * append_tab)
583{
584 size_t extra_size;
585 int r;
586 char from_line[MAX_FROM_LINE_SIZE] = DEFAULT_FROM_LINE;
587 struct tm time_info;
588 time_t date;
589 int res;
590 size_t old_size;
591 char * str;
592 unsigned int i;
593 size_t from_size;
594 size_t maxuid;
595 size_t left;
596 size_t crlf_count;
597
598 if (folder->mb_read_only) {
599 res = MAILMBOX_ERROR_READONLY;
600 goto err;
601 }
602
603 date = time(NULL);
604 from_size = strlen(DEFAULT_FROM_LINE);
605 if (localtime_r(&date, &time_info) != NULL)
606 from_size = strftime(from_line, MAX_FROM_LINE_SIZE, "From - %c\n", &time_info);
607
608 maxuid = /* */ folder->mb_max_uid;
609
610 extra_size = 0;
611 for(i = 0 ; i < carray_count(append_tab) ; i ++) {
612 struct mailmbox_append_info * info;
613
614 info = carray_get(append_tab, i);
615 extra_size += from_size;
616 extra_size += get_fixed_message_size(info->ai_message, info->ai_size,
617 folder->mb_max_uid + i + 1,
618 folder->mb_no_uid);
619 extra_size += 2; /* CR LF */
620 }
621
622 left = folder->mb_mapping_size;
623 crlf_count = 0;
624 while (left >= 1) {
625 if (folder->mb_mapping[left - 1] == '\n') {
626 crlf_count ++;
627 left --;
628 }
629 else if (folder->mb_mapping[left - 1] == '\r') {
630 left --;
631 }
632 else
633 break;
634
635 if (crlf_count == 2)
636 break;
637 }
638
639 old_size = folder->mb_mapping_size;
640 mailmbox_unmap(folder);
641
642 if (old_size != 0) {
643 if (crlf_count != 2)
644 extra_size += (2 - crlf_count) * 2;
645 }
646
647 r = ftruncate(folder->mb_fd, extra_size + old_size);
648 if (r < 0) {
649 mailmbox_map(folder);
650 res = MAILMBOX_ERROR_FILE;
651 goto err;
652 }
653
654 r = mailmbox_map(folder);
655 if (r < 0) {
656 ftruncate(folder->mb_fd, old_size);
657 return MAILMBOX_ERROR_FILE;
658 }
659
660 str = folder->mb_mapping + old_size;
661
662 if (old_size != 0) {
663 for(i = 0 ; i < 2 - crlf_count ; i ++) {
664 * str = '\r';
665 str ++;
666 * str = '\n';
667 str ++;
668 }
669 }
670
671 for(i = 0 ; i < carray_count(append_tab) ; i ++) {
672 struct mailmbox_append_info * info;
673
674 info = carray_get(append_tab, i);
675
676 memcpy(str, from_line, from_size);
677
678 str += strlen(from_line);
679
680 str = write_fixed_message(str, info->ai_message, info->ai_size,
681 folder->mb_max_uid + i + 1,
682 folder->mb_no_uid);
683
684 * str = '\r';
685 str ++;
686 * str = '\n';
687 str ++;
688 }
689
690 folder->mb_max_uid += carray_count(append_tab);
691
692 return MAILMBOX_NO_ERROR;
693
694 err:
695 return res;
696}
697
698int
699mailmbox_append_message_list(struct mailmbox_folder * folder,
700 carray * append_tab)
701{
702 int r;
703 int res;
704 size_t cur_token;
705
706 r = mailmbox_validate_write_lock(folder);
707 if (r != MAILMBOX_NO_ERROR) {
708 res = r;
709 goto err;
710 }
711
712 r = mailmbox_expunge_no_lock(folder);
713 if (r != MAILMBOX_NO_ERROR) {
714 res = r;
715 goto unlock;
716 }
717
718 cur_token = folder->mb_mapping_size;
719
720 r = mailmbox_append_message_list_no_lock(folder, append_tab);
721 if (r != MAILMBOX_NO_ERROR) {
722 res = r;
723 goto unlock;
724 }
725
726 mailmbox_sync(folder);
727
728 r = mailmbox_parse_additionnal(folder, &cur_token);
729 if (r != MAILMBOX_NO_ERROR) {
730 res = r;
731 goto unlock;
732 }
733
734 mailmbox_timestamp(folder);
735
736 mailmbox_write_unlock(folder);
737
738 return MAILMBOX_NO_ERROR;
739
740 unlock:
741 mailmbox_write_unlock(folder);
742 err:
743 return res;
744}
745
746int
747mailmbox_append_message(struct mailmbox_folder * folder,
748 const char * data, size_t len)
749{
750 carray * tab;
751 struct mailmbox_append_info * append_info;
752 int res;
753 int r;
754
755 tab = carray_new(1);
756 if (tab == NULL) {
757 res = MAILMBOX_ERROR_MEMORY;
758 goto err;
759 }
760
761 append_info = mailmbox_append_info_new(data, len);
762 if (append_info == NULL) {
763 res = MAILMBOX_ERROR_MEMORY;
764 goto free_list;
765 }
766
767 r = carray_add(tab, append_info, NULL);
768 if (r < 0) {
769 res = MAILMBOX_ERROR_MEMORY;
770 goto free_append_info;
771 }
772
773 r = mailmbox_append_message_list(folder, tab);
774
775 mailmbox_append_info_free(append_info);
776 carray_free(tab);
777
778 return r;
779
780 free_append_info:
781 mailmbox_append_info_free(append_info);
782 free_list:
783 carray_free(tab);
784 err:
785 return res;
786}
787
788/* ********************************************************************** */
789
790int mailmbox_fetch_msg_no_lock(struct mailmbox_folder * folder,
791 uint32_t num, char ** result,
792 size_t * result_len)
793{
794 struct mailmbox_msg_info * info;
795 int res;
796 chashdatum key;
797 chashdatum data;
798 int r;
799
800 key.data = &num;
801 key.len = sizeof(num);
802
803 r = chash_get(folder->mb_hash, &key, &data);
804 if (r < 0) {
805 res = MAILMBOX_ERROR_MSG_NOT_FOUND;
806 goto err;
807 }
808
809 info = data.data;
810
811 if (info->msg_deleted) {
812 res = MAILMBOX_ERROR_MSG_NOT_FOUND;
813 goto err;
814 }
815
816 * result = folder->mb_mapping + info->msg_headers;
817 * result_len = info->msg_size - info->msg_start_len;
818
819 return MAILMBOX_NO_ERROR;
820
821 err:
822 return res;
823}
824
825int mailmbox_fetch_msg_headers_no_lock(struct mailmbox_folder * folder,
826 uint32_t num, char ** result,
827 size_t * result_len)
828{
829 struct mailmbox_msg_info * info;
830 int res;
831 chashdatum key;
832 chashdatum data;
833 int r;
834
835 key.data = &num;
836 key.len = sizeof(num);
837
838 r = chash_get(folder->mb_hash, &key, &data);
839 if (r < 0) {
840 res = MAILMBOX_ERROR_MSG_NOT_FOUND;
841 goto err;
842 }
843
844 info = data.data;
845
846 if (info->msg_deleted) {
847 res = MAILMBOX_ERROR_MSG_NOT_FOUND;
848 goto err;
849 }
850
851 * result = folder->mb_mapping + info->msg_headers;
852 * result_len = info->msg_headers_len;
853
854 return MAILMBOX_NO_ERROR;
855
856 err:
857 return res;
858}
859
860int mailmbox_fetch_msg(struct mailmbox_folder * folder,
861 uint32_t num, char ** result,
862 size_t * result_len)
863{
864 MMAPString * mmapstr;
865 int res;
866 char * data;
867 size_t len;
868 int r;
869 size_t fixed_size;
870 char * end;
871
872 r = mailmbox_validate_read_lock(folder);
873 if (r != MAILMBOX_NO_ERROR) {
874 res = r;
875 goto err;
876 }
877
878 r = mailmbox_fetch_msg_no_lock(folder, num, &data, &len);
879 if (r != MAILMBOX_NO_ERROR) {
880 res = r;
881 goto unlock;
882 }
883
884 /* size with no uid */
885 fixed_size = get_fixed_message_size(data, len, 0, 1 /* force no uid */);
886
887#if 0
888 mmapstr = mmap_string_new_len(data, fixed_size);
889 if (mmapstr == NULL) {
890 res = MAILMBOX_ERROR_MEMORY;
891 goto unlock;
892 }
893#endif
894 mmapstr = mmap_string_sized_new(fixed_size);
895 if (mmapstr == NULL) {
896 res = MAILMBOX_ERROR_MEMORY;
897 goto unlock;
898 }
899
900 end = write_fixed_message(mmapstr->str, data, len, 0, 1 /* force no uid */);
901 * end = '\0';
902 mmapstr->len = fixed_size;
903
904 r = mmap_string_ref(mmapstr);
905 if (r < 0) {
906 mmap_string_free(mmapstr);
907 res = MAILMBOX_ERROR_MEMORY;
908 goto unlock;
909 }
910
911 * result = mmapstr->str;
912 * result_len = mmapstr->len;
913
914 mailmbox_read_unlock(folder);
915
916 return MAILMBOX_NO_ERROR;
917
918 unlock:
919 mailmbox_read_unlock(folder);
920 err:
921 return res;
922}
923
924int mailmbox_fetch_msg_headers(struct mailmbox_folder * folder,
925 uint32_t num, char ** result,
926 size_t * result_len)
927{
928 MMAPString * mmapstr;
929 int res;
930 char * data;
931 size_t len;
932 int r;
933 size_t fixed_size;
934 char * end;
935
936 r = mailmbox_validate_read_lock(folder);
937 if (r != MAILMBOX_NO_ERROR) {
938 res = r;
939 goto err;
940 }
941
942 r = mailmbox_fetch_msg_headers_no_lock(folder, num, &data, &len);
943 if (r != MAILMBOX_NO_ERROR) {
944 res = r;
945 goto unlock;
946 }
947
948#if 0
949 mmapstr = mmap_string_new_len(data, len);
950 if (mmapstr == NULL) {
951 res = MAILMBOX_ERROR_MEMORY;
952 goto unlock;
953 }
954#endif
955 /* size with no uid */
956 fixed_size = get_fixed_message_size(data, len, 0, 1 /* force no uid */);
957
958 mmapstr = mmap_string_sized_new(fixed_size);
959 if (mmapstr == NULL) {
960 res = MAILMBOX_ERROR_MEMORY;
961 goto unlock;
962 }
963
964 end = write_fixed_message(mmapstr->str, data, len, 0, 1 /* force no uid */);
965 * end = '\0';
966 mmapstr->len = fixed_size;
967
968 r = mmap_string_ref(mmapstr);
969 if (r < 0) {
970 mmap_string_free(mmapstr);
971 res = MAILMBOX_ERROR_MEMORY;
972 goto unlock;
973 }
974
975 * result = mmapstr->str;
976 * result_len = mmapstr->len;
977
978 mailmbox_read_unlock(folder);
979
980 return MAILMBOX_NO_ERROR;
981
982 unlock:
983 mailmbox_read_unlock(folder);
984 err:
985 return res;
986}
987
988void mailmbox_fetch_result_free(char * msg)
989{
990 mmap_string_unref(msg);
991}
992
993
994int mailmbox_copy_msg_list(struct mailmbox_folder * dest_folder,
995 struct mailmbox_folder * src_folder,
996 carray * tab)
997{
998 int r;
999 int res;
1000 carray * append_tab;
1001 unsigned int i;
1002
1003 r = mailmbox_validate_read_lock(src_folder);
1004 if (r != MAILMBOX_NO_ERROR) {
1005 res = r;
1006 goto err;
1007 }
1008
1009 append_tab = carray_new(carray_count(tab));
1010 if (append_tab == NULL) {
1011 res = MAILMBOX_ERROR_MEMORY;
1012 goto src_unlock;
1013 }
1014
1015 for(i = 0 ; i < carray_count(tab) ; i ++) {
1016 struct mailmbox_append_info * append_info;
1017 char * data;
1018 size_t len;
1019 uint32_t uid;
1020
1021 uid = * ((uint32_t *) carray_get(tab, i));
1022
1023 r = mailmbox_fetch_msg_no_lock(src_folder, uid, &data, &len);
1024 if (r != MAILMBOX_NO_ERROR) {
1025 res = r;
1026 goto free_list;
1027 }
1028
1029 append_info = mailmbox_append_info_new(data, len);
1030 if (append_info == NULL) {
1031 res = MAILMBOX_ERROR_MEMORY;
1032 goto free_list;
1033 }
1034
1035 r = carray_add(append_tab, append_info, NULL);
1036 if (r < 0) {
1037 mailmbox_append_info_free(append_info);
1038 res = MAILMBOX_ERROR_MEMORY;
1039 goto free_list;
1040 }
1041 }
1042
1043 r = mailmbox_append_message_list(dest_folder, append_tab);
1044 if (r != MAILMBOX_NO_ERROR) {
1045 res = r;
1046 goto src_unlock;
1047 }
1048
1049 for(i = 0 ; i < carray_count(append_tab) ; i ++) {
1050 struct mailmbox_append_info * append_info;
1051
1052 append_info = carray_get(append_tab, i);
1053 mailmbox_append_info_free(append_info);
1054 }
1055 carray_free(append_tab);
1056
1057 mailmbox_read_unlock(src_folder);
1058
1059 return MAILMBOX_NO_ERROR;
1060
1061 free_list:
1062 for(i = 0 ; i < carray_count(append_tab) ; i ++) {
1063 struct mailmbox_append_info * append_info;
1064
1065 append_info = carray_get(append_tab, i);
1066 mailmbox_append_info_free(append_info);
1067 }
1068 carray_free(append_tab);
1069 src_unlock:
1070 mailmbox_read_unlock(src_folder);
1071 err:
1072 return res;
1073}
1074
1075int mailmbox_copy_msg(struct mailmbox_folder * dest_folder,
1076 struct mailmbox_folder * src_folder,
1077 uint32_t uid)
1078{
1079 carray * tab;
1080 int res;
1081 uint32_t * puid;
1082 int r;
1083
1084 tab = carray_new(1);
1085 if (tab == NULL) {
1086 res = MAILMBOX_ERROR_MEMORY;
1087 goto err;
1088 }
1089
1090 puid = malloc(sizeof(* puid));
1091 if (puid == NULL) {
1092 res = MAILMBOX_ERROR_MEMORY;
1093 goto free_array;
1094 }
1095 * puid = uid;
1096
1097 r = mailmbox_copy_msg_list(dest_folder, src_folder, tab);
1098 res = r;
1099
1100 free(puid);
1101 free_array:
1102 carray_free(tab);
1103 err:
1104 return res;
1105}
1106
1107static int mailmbox_expunge_to_file_no_lock(char * dest_filename, int dest_fd,
1108 struct mailmbox_folder * folder,
1109 size_t * result_size)
1110{
1111 int r;
1112 int res;
1113 unsigned long i;
1114 size_t cur_offset;
1115 char * dest;
1116 size_t size;
1117
1118 size = 0;
1119 for(i = 0 ; i < carray_count(folder->mb_tab) ; i ++) {
1120 struct mailmbox_msg_info * info;
1121
1122 info = carray_get(folder->mb_tab, i);
1123
1124 if (!info->msg_deleted) {
1125 size += info->msg_size + info->msg_padding;
1126
1127 if (!folder->mb_no_uid) {
1128 if (!info->msg_written_uid) {
1129 uint32_t uid;
1130
1131 size += strlen(UID_HEADER " \r\n");
1132
1133 uid = info->msg_uid;
1134 while (uid >= 10) {
1135 uid /= 10;
1136 size ++;
1137 }
1138 size ++;
1139 }
1140 }
1141 }
1142 }
1143
1144 r = ftruncate(dest_fd, size);
1145 if (r < 0) {
1146 res = MAILMBOX_ERROR_FILE;
1147 goto err;
1148 }
1149
1150 dest = (char *) mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, dest_fd, 0);
1151 if (dest == MAP_FAILED) {
1152 res = MAILMBOX_ERROR_FILE;
1153 goto err;
1154 }
1155
1156 cur_offset = 0;
1157 for(i = 0 ; i < carray_count(folder->mb_tab) ; i ++) {
1158 struct mailmbox_msg_info * info;
1159
1160 info = carray_get(folder->mb_tab, i);
1161
1162 if (!info->msg_deleted) {
1163 memcpy(dest + cur_offset, folder->mb_mapping + info->msg_start,
1164 info->msg_headers_len + info->msg_start_len);
1165 cur_offset += info->msg_headers_len + info->msg_start_len;
1166
1167 if (!folder->mb_no_uid) {
1168 if (!info->msg_written_uid) {
1169 size_t numlen;
1170
1171 memcpy(dest + cur_offset, UID_HEADER " ", strlen(UID_HEADER " "));
1172 cur_offset += strlen(UID_HEADER " ");
1173 numlen = snprintf(dest + cur_offset, size - cur_offset,
1174 "%i\r\n", info->msg_uid);
1175 cur_offset += numlen;
1176 }
1177 }
1178
1179 memcpy(dest + cur_offset,
1180 folder->mb_mapping + info->msg_headers + info->msg_headers_len,
1181 info->msg_size - (info->msg_start_len + info->msg_headers_len)
1182 + info->msg_padding);
1183
1184 cur_offset += info->msg_size -
1185 (info->msg_start_len + info->msg_headers_len)
1186 + info->msg_padding;
1187 }
1188 }
1189 fflush(stdout);
1190
1191 msync(dest, size, MS_SYNC);
1192 munmap(dest, size);
1193
1194 * result_size = size;
1195
1196 return MAILMBOX_NO_ERROR;
1197
1198 err:
1199 return res;
1200}
1201
1202int mailmbox_expunge_no_lock(struct mailmbox_folder * folder)
1203{
1204 char tmpfile[PATH_MAX];
1205 int r;
1206 int res;
1207 int dest_fd;
1208 size_t size;
1209
1210 if (folder->mb_read_only)
1211 return MAILMBOX_ERROR_READONLY;
1212
1213 if (((folder->mb_written_uid >= folder->mb_max_uid) || folder->mb_no_uid) &&
1214 (!folder->mb_changed)) {
1215 /* no need to expunge */
1216 return MAILMBOX_NO_ERROR;
1217 }
1218
1219 snprintf(tmpfile, PATH_MAX, "%sXXXXXX", folder->mb_filename);
1220 dest_fd = mkstemp(tmpfile);
1221
1222 if (dest_fd < 0) {
1223 res = MAILMBOX_ERROR_FILE;
1224 goto unlink;
1225 }
1226
1227 r = mailmbox_expunge_to_file_no_lock(tmpfile, dest_fd,
1228 folder, &size);
1229 if (r != MAILMBOX_NO_ERROR) {
1230 res = r;
1231 goto unlink;
1232 }
1233
1234 close(dest_fd);
1235
1236 r = rename(tmpfile, folder->mb_filename);
1237 if (r < 0) {
1238 res = r;
1239 goto err;
1240 }
1241
1242 mailmbox_unmap(folder);
1243 mailmbox_close(folder);
1244
1245 r = mailmbox_open(folder);
1246 if (r != MAILMBOX_NO_ERROR) {
1247 res = r;
1248 goto err;
1249 }
1250
1251 r = mailmbox_map(folder);
1252 if (r != MAILMBOX_NO_ERROR) {
1253 res = r;
1254 goto err;
1255 }
1256
1257 r = mailmbox_parse(folder);
1258 if (r != MAILMBOX_NO_ERROR) {
1259 res = r;
1260 goto err;
1261 }
1262
1263 mailmbox_timestamp(folder);
1264
1265 folder->mb_changed = FALSE;
1266 folder->mb_deleted_count = 0;
1267
1268 return MAILMBOX_NO_ERROR;
1269
1270 unlink:
1271 close(dest_fd);
1272 unlink(tmpfile);
1273 err:
1274 return res;
1275}
1276
1277int mailmbox_expunge(struct mailmbox_folder * folder)
1278{
1279 int r;
1280 int res;
1281
1282 r = mailmbox_validate_write_lock(folder);
1283 if (r != MAILMBOX_NO_ERROR) {
1284 res = r;
1285 goto err;
1286 }
1287
1288 r = mailmbox_expunge_no_lock(folder);
1289 res = r;
1290
1291 mailmbox_write_unlock(folder);
1292 err:
1293 return res;
1294}
1295
1296int mailmbox_delete_msg(struct mailmbox_folder * folder, uint32_t uid)
1297{
1298 struct mailmbox_msg_info * info;
1299 int res;
1300 chashdatum key;
1301 chashdatum data;
1302 int r;
1303
1304 if (folder->mb_read_only) {
1305 res = MAILMBOX_ERROR_READONLY;
1306 goto err;
1307 }
1308
1309 key.data = &uid;
1310 key.len = sizeof(uid);
1311
1312 r = chash_get(folder->mb_hash, &key, &data);
1313 if (r < 0) {
1314 res = MAILMBOX_ERROR_MSG_NOT_FOUND;
1315 goto err;
1316 }
1317
1318 info = data.data;
1319
1320 if (info->msg_deleted) {
1321 res = MAILMBOX_ERROR_MSG_NOT_FOUND;
1322 goto err;
1323 }
1324
1325 info->msg_deleted = TRUE;
1326 folder->mb_changed = TRUE;
1327 folder->mb_deleted_count ++;
1328
1329 return MAILMBOX_NO_ERROR;
1330
1331 err:
1332 return res;
1333}
1334
1335
1336/*
1337 INIT of MBOX
1338
1339 - open file
1340 - map the file
1341
1342 - lock the file
1343
1344 - parse memory
1345
1346 - unlock the file
1347*/
1348
1349int mailmbox_init(const char * filename,
1350 int force_readonly,
1351 int force_no_uid,
1352 uint32_t default_written_uid,
1353 struct mailmbox_folder ** result_folder)
1354{
1355 struct mailmbox_folder * folder;
1356 int r;
1357 int res;
1358
1359 folder = mailmbox_folder_new(filename);
1360 if (folder == NULL) {
1361 res = MAILMBOX_ERROR_MEMORY;
1362 goto err;
1363 }
1364 folder->mb_no_uid = force_no_uid;
1365 folder->mb_read_only = force_readonly;
1366 folder->mb_written_uid = default_written_uid;
1367
1368 folder->mb_changed = FALSE;
1369 folder->mb_deleted_count = 0;
1370
1371 r = mailmbox_open(folder);
1372 if (r != MAILMBOX_NO_ERROR) {
1373 res = r;
1374 goto free;
1375 }
1376
1377 r = mailmbox_map(folder);
1378 if (r != MAILMBOX_NO_ERROR) {
1379 res = r;
1380 goto close;
1381 }
1382
1383 r = mailmbox_validate_read_lock(folder);
1384 if (r != MAILMBOX_NO_ERROR) {
1385 res = r;
1386 goto unmap;
1387 }
1388
1389 mailmbox_read_unlock(folder);
1390
1391 * result_folder = folder;
1392
1393 return MAILMBOX_NO_ERROR;
1394
1395 unmap:
1396 mailmbox_unmap(folder);
1397 close:
1398 mailmbox_close(folder);
1399 free:
1400 mailmbox_folder_free(folder);
1401 err:
1402 return res;
1403}
1404
1405
1406/*
1407 when MBOX is DONE
1408
1409 - check for changes
1410
1411 - unmap the file
1412 - close file
1413*/
1414
1415void mailmbox_done(struct mailmbox_folder * folder)
1416{
1417 if (!folder->mb_read_only)
1418 mailmbox_expunge(folder);
1419
1420 mailmbox_unmap(folder);
1421 mailmbox_close(folder);
1422
1423 mailmbox_folder_free(folder);
1424}
diff --git a/kmicromail/libetpan/mbox/mailmbox.h b/kmicromail/libetpan/mbox/mailmbox.h
new file mode 100644
index 0000000..8be086c
--- a/dev/null
+++ b/kmicromail/libetpan/mbox/mailmbox.h
@@ -0,0 +1,140 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMBOX_H
37
38#define MAILMBOX_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailmbox_types.h>
45
46int
47mailmbox_append_message_list(struct mailmbox_folder * folder,
48 carray * append_tab);
49
50int
51mailmbox_append_message(struct mailmbox_folder * folder,
52 const char * data, size_t len);
53
54int mailmbox_fetch_msg(struct mailmbox_folder * folder,
55 uint32_t num, char ** result,
56 size_t * result_len);
57
58int mailmbox_fetch_msg_headers(struct mailmbox_folder * folder,
59 uint32_t num, char ** result,
60 size_t * result_len);
61
62void mailmbox_fetch_result_free(char * msg);
63
64int mailmbox_copy_msg_list(struct mailmbox_folder * dest_folder,
65 struct mailmbox_folder * src_folder,
66 carray * tab);
67
68int mailmbox_copy_msg(struct mailmbox_folder * dest_folder,
69 struct mailmbox_folder * src_folder,
70 uint32_t uid);
71
72int mailmbox_expunge(struct mailmbox_folder * folder);
73
74int mailmbox_delete_msg(struct mailmbox_folder * folder, uint32_t uid);
75
76int mailmbox_init(const char * filename,
77 int force_readonly,
78 int force_no_uid,
79 uint32_t default_written_uid,
80 struct mailmbox_folder ** result_folder);
81
82void mailmbox_done(struct mailmbox_folder * folder);
83
84/* low-level access primitives */
85
86int mailmbox_write_lock(struct mailmbox_folder * folder);
87
88int mailmbox_write_unlock(struct mailmbox_folder * folder);
89
90int mailmbox_read_lock(struct mailmbox_folder * folder);
91
92int mailmbox_read_unlock(struct mailmbox_folder * folder);
93
94
95/* memory map */
96
97int mailmbox_map(struct mailmbox_folder * folder);
98
99void mailmbox_unmap(struct mailmbox_folder * folder);
100
101void mailmbox_sync(struct mailmbox_folder * folder);
102
103
104/* open & close file */
105
106int mailmbox_open(struct mailmbox_folder * folder);
107
108void mailmbox_close(struct mailmbox_folder * folder);
109
110
111/* validate cache */
112
113int mailmbox_validate_write_lock(struct mailmbox_folder * folder);
114
115int mailmbox_validate_read_lock(struct mailmbox_folder * folder);
116
117
118/* fetch message */
119
120int mailmbox_fetch_msg_no_lock(struct mailmbox_folder * folder,
121 uint32_t num, char ** result,
122 size_t * result_len);
123
124int mailmbox_fetch_msg_headers_no_lock(struct mailmbox_folder * folder,
125 uint32_t num, char ** result,
126 size_t * result_len);
127
128/* append message */
129
130int
131mailmbox_append_message_list_no_lock(struct mailmbox_folder * folder,
132 carray * append_tab);
133
134int mailmbox_expunge_no_lock(struct mailmbox_folder * folder);
135
136#ifdef __cplusplus
137}
138#endif
139
140#endif
diff --git a/kmicromail/libetpan/mbox/mailmbox_parse.c b/kmicromail/libetpan/mbox/mailmbox_parse.c
new file mode 100644
index 0000000..927159c
--- a/dev/null
+++ b/kmicromail/libetpan/mbox/mailmbox_parse.c
@@ -0,0 +1,620 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailmbox_parse.h"
37
38#include "mailmbox.h"
39
40#include <sys/types.h>
41#include <sys/stat.h>
42#include <string.h>
43#include <stdlib.h>
44
45#define UID_HEADER "X-LibEtPan-UID:"
46
47#ifndef TRUE
48#define TRUE 1
49#endif
50
51#ifndef FALSE
52#define FALSE 0
53#endif
54
55enum {
56 UNSTRUCTURED_START,
57 UNSTRUCTURED_CR,
58 UNSTRUCTURED_LF,
59 UNSTRUCTURED_WSP,
60 UNSTRUCTURED_OUT
61};
62
63static inline int
64mailmbox_fields_parse(char * str, size_t length,
65 size_t * index,
66 uint32_t * puid,
67 size_t * phlen)
68{
69 size_t cur_token;
70 int r;
71 size_t hlen;
72 size_t uid;
73 int end;
74
75 cur_token = * index;
76
77 end = FALSE;
78 uid = 0;
79 while (!end) {
80 size_t begin;
81
82 begin = cur_token;
83
84 r = mailimf_ignore_field_parse(str, length, &cur_token);
85 switch (r) {
86 case MAILIMF_NO_ERROR:
87 if (str[begin] == 'X') {
88
89 if (strncasecmp(str + begin, UID_HEADER, strlen(UID_HEADER)) == 0) {
90 begin += strlen(UID_HEADER);
91
92 while (str[begin] == ' ')
93 begin ++;
94
95 uid = strtoul(str + begin, NULL, 10);
96 }
97 }
98
99 break;
100 case MAILIMF_ERROR_PARSE:
101 default:
102 end = TRUE;
103 break;
104 }
105 }
106
107 hlen = cur_token - * index;
108
109 * phlen = hlen;
110 * puid = uid;
111 * index = cur_token;
112
113 return MAILMBOX_NO_ERROR;
114}
115
116enum {
117 IN_MAIL,
118 FIRST_CR,
119 FIRST_LF,
120 SECOND_CR,
121 SECOND_LF,
122 PARSING_F,
123 PARSING_R,
124 PARSING_O,
125 PARSING_M,
126 OUT_MAIL
127};
128
129
130
131
132static inline int
133mailmbox_single_parse(char * str, size_t length,
134 size_t * index,
135 size_t * pstart,
136 size_t * pstart_len,
137 size_t * pheaders,
138 size_t * pheaders_len,
139 size_t * pbody,
140 size_t * pbody_len,
141 size_t * psize,
142 size_t * ppadding,
143 uint32_t * puid)
144{
145 size_t cur_token;
146 size_t start;
147 size_t start_len;
148 size_t headers;
149 size_t headers_len;
150 size_t body;
151 size_t end;
152 size_t next;
153 size_t message_length;
154 uint32_t uid;
155 int r;
156#if 0
157 int in_mail_data;
158#endif
159#if 0
160 size_t begin;
161#endif
162
163 int state;
164
165 cur_token = * index;
166
167 if (cur_token >= length)
168 return MAILMBOX_ERROR_PARSE;
169
170 start = cur_token;
171 start_len = 0;
172 headers = cur_token;
173
174 if (cur_token + 5 < length) {
175 if (strncmp(str + cur_token, "From ", 5) == 0) {
176 cur_token += 5;
177 while (str[cur_token] != '\n') {
178 cur_token ++;
179 if (cur_token >= length)
180 break;
181 }
182 if (cur_token < length) {
183 cur_token ++;
184 headers = cur_token;
185 start_len = headers - start;
186 }
187 }
188 }
189
190 next = length;
191
192 r = mailmbox_fields_parse(str, length, &cur_token,
193 &uid, &headers_len);
194 if (r != MAILMBOX_NO_ERROR)
195 return r;
196
197 /* save position */
198#if 0
199 begin = cur_token;
200#endif
201
202 mailimf_crlf_parse(str, length, &cur_token);
203
204#if 0
205 if (str[cur_token] == 'F') {
206 printf("start !\n");
207 printf("%50.50s\n", str + cur_token);
208 getchar();
209 }
210#endif
211
212 body = cur_token;
213
214 /* restore position */
215 /* cur_token = begin; */
216
217 state = FIRST_LF;
218
219 end = length;
220
221#if 0
222 in_mail_data = 0;
223#endif
224 while (state != OUT_MAIL) {
225
226 if (cur_token >= length) {
227 if (state == IN_MAIL)
228 end = length;
229 next = length;
230 break;
231 }
232
233 switch(state) {
234 case IN_MAIL:
235 switch(str[cur_token]) {
236 case '\r':
237 state = FIRST_CR;
238 break;
239 case '\n':
240 state = FIRST_LF;
241 break;
242 case 'F':
243 if (cur_token == body) {
244 end = cur_token;
245 next = cur_token;
246 state = PARSING_F;
247 }
248 break;
249#if 0
250 default:
251 in_mail_data = 1;
252 break;
253#endif
254 }
255 break;
256
257 case FIRST_CR:
258 end = cur_token;
259 switch(str[cur_token]) {
260 case '\r':
261 state = SECOND_CR;
262 break;
263 case '\n':
264 state = FIRST_LF;
265 break;
266 default:
267 state = IN_MAIL;
268#if 0
269 in_mail_data = 1;
270#endif
271 break;
272 }
273 break;
274
275 case FIRST_LF:
276 end = cur_token;
277 switch(str[cur_token]) {
278 case '\r':
279 state = SECOND_CR;
280 break;
281 case '\n':
282 state = SECOND_LF;
283 break;
284 default:
285 state = IN_MAIL;
286#if 0
287 in_mail_data = 1;
288#endif
289 break;
290 }
291 break;
292
293 case SECOND_CR:
294 switch(str[cur_token]) {
295 case '\r':
296 end = cur_token;
297 break;
298 case '\n':
299 state = SECOND_LF;
300 break;
301 case 'F':
302 next = cur_token;
303 state = PARSING_F;
304 break;
305 default:
306 state = IN_MAIL;
307#if 0
308 in_mail_data = 1;
309#endif
310 break;
311 }
312 break;
313
314 case SECOND_LF:
315 switch(str[cur_token]) {
316 case '\r':
317 state = SECOND_CR;
318 break;
319 case '\n':
320 end = cur_token;
321 break;
322 case 'F':
323 next = cur_token;
324 state = PARSING_F;
325 break;
326 default:
327 state = IN_MAIL;
328#if 0
329 in_mail_data = 1;
330#endif
331 break;
332 }
333 break;
334
335 case PARSING_F:
336 switch(str[cur_token]) {
337 case 'r':
338 state = PARSING_R;
339 break;
340 default:
341 state = IN_MAIL;
342#if 0
343 in_mail_data = 1;
344#endif
345 break;
346 }
347 break;
348
349 case PARSING_R:
350 switch(str[cur_token]) {
351 case 'o':
352 state = PARSING_O;
353 break;
354 default:
355 state = IN_MAIL;
356#if 0
357 in_mail_data = 1;
358#endif
359 break;
360 }
361 break;
362
363 case PARSING_O:
364 switch(str[cur_token]) {
365 case 'm':
366 state = PARSING_M;
367 break;
368 default:
369 state = IN_MAIL;
370#if 0
371 in_mail_data = 1;
372#endif
373 break;
374 }
375 break;
376
377 case PARSING_M:
378 switch(str[cur_token]) {
379 case ' ':
380 state = OUT_MAIL;
381 break;
382 default:
383 state = IN_MAIL;
384 break;
385 }
386 break;
387 }
388
389 cur_token ++;
390 }
391
392 message_length = end - start;
393
394 * pstart = start;
395 * pstart_len = start_len;
396 * pheaders = headers;
397 * pheaders_len = headers_len;
398 * pbody = body;
399 * pbody_len = end - body;
400 * psize = message_length;
401 * ppadding = next - end;
402 * puid = uid;
403
404 * index = next;
405
406 return MAILMBOX_NO_ERROR;
407}
408
409
410int
411mailmbox_parse_additionnal(struct mailmbox_folder * folder,
412 size_t * index)
413{
414 size_t cur_token;
415
416 size_t start;
417 size_t start_len;
418 size_t headers;
419 size_t headers_len;
420 size_t body;
421 size_t body_len;
422 size_t size;
423 size_t padding;
424 uint32_t uid;
425 int r;
426 int res;
427
428 uint32_t max_uid;
429 uint32_t first_index;
430 unsigned int i;
431 unsigned int j;
432
433 cur_token = * index;
434
435 /* remove temporary UID that we will parse */
436
437 first_index = carray_count(folder->mb_tab);
438
439 for(i = 0 ; i < carray_count(folder->mb_tab) ; i++) {
440 struct mailmbox_msg_info * info;
441
442 info = carray_get(folder->mb_tab, i);
443
444 if (info->msg_start < cur_token) {
445 continue;
446 }
447
448 if (!info->msg_written_uid) {
449 chashdatum key;
450
451 key.data = &info->msg_uid;
452 key.len = sizeof(info->msg_uid);
453
454 chash_delete(folder->mb_hash, &key, NULL);
455 carray_delete_fast(folder->mb_tab, i);
456 mailmbox_msg_info_free(info);
457 if (i < first_index)
458 first_index = i;
459 }
460 }
461
462 /* make a sequence in the table */
463
464 max_uid = folder->mb_written_uid;
465
466 i = 0;
467 j = 0;
468 while (i < carray_count(folder->mb_tab)) {
469 struct mailmbox_msg_info * info;
470
471 info = carray_get(folder->mb_tab, i);
472 if (info != NULL) {
473 carray_set(folder->mb_tab, j, info);
474
475 if (info->msg_uid > max_uid)
476 max_uid = info->msg_uid;
477
478 info->msg_index = j;
479 j ++;
480 }
481 i ++;
482 }
483 carray_set_size(folder->mb_tab, j);
484
485 /* parse content */
486
487 first_index = j;
488
489 while (1) {
490 struct mailmbox_msg_info * info;
491 chashdatum key;
492 chashdatum data;
493
494 r = mailmbox_single_parse(folder->mb_mapping, folder->mb_mapping_size,
495 &cur_token,
496 &start, &start_len,
497 &headers, &headers_len,
498 &body, &body_len,
499 &size, &padding, &uid);
500 if (r == MAILMBOX_NO_ERROR) {
501 /* do nothing */
502 }
503 else if (r == MAILMBOX_ERROR_PARSE)
504 break;
505 else {
506 res = r;
507 goto err;
508 }
509
510 key.data = &uid;
511 key.len = sizeof(uid);
512
513 r = chash_get(folder->mb_hash, &key, &data);
514 if (r == 0) {
515 info = data.data;
516
517 if (!info->msg_written_uid) {
518 /* some new mail has been written and override an
519 existing temporary UID */
520
521 chash_delete(folder->mb_hash, &key, NULL);
522 info->msg_uid = 0;
523
524 if (info->msg_index < first_index)
525 first_index = info->msg_index;
526 }
527 else
528 uid = 0;
529 }
530
531 if (uid > max_uid)
532 max_uid = uid;
533
534 r = mailmbox_msg_info_update(folder,
535 start, start_len, headers, headers_len,
536 body, body_len, size, padding, uid);
537 if (r != MAILMBOX_NO_ERROR) {
538 res = r;
539 goto err;
540 }
541 }
542
543 * index = cur_token;
544
545 folder->mb_written_uid = max_uid;
546
547 /* attribute uid */
548
549 for(i = first_index ; i < carray_count(folder->mb_tab) ; i ++) {
550 struct mailmbox_msg_info * info;
551 chashdatum key;
552 chashdatum data;
553
554 info = carray_get(folder->mb_tab, i);
555
556 if (info->msg_uid != 0) {
557 continue;
558 }
559
560 max_uid ++;
561 info->msg_uid = max_uid;
562
563 key.data = &info->msg_uid;
564 key.len = sizeof(info->msg_uid);
565 data.data = info;
566 data.len = 0;
567
568 r = chash_set(folder->mb_hash, &key, &data, NULL);
569 if (r < 0) {
570 res = MAILMBOX_ERROR_MEMORY;
571 goto err;
572 }
573 }
574
575 folder->mb_max_uid = max_uid;
576
577 return MAILMBOX_NO_ERROR;
578
579 err:
580 return res;
581}
582
583static void flush_uid(struct mailmbox_folder * folder)
584{
585 unsigned int i;
586
587 for(i = 0 ; i < carray_count(folder->mb_tab) ; i++) {
588 struct mailmbox_msg_info * info;
589
590 info = carray_get(folder->mb_tab, i);
591 if (info != NULL)
592 mailmbox_msg_info_free(info);
593 }
594
595 chash_clear(folder->mb_hash);
596 carray_set_size(folder->mb_tab, 0);
597}
598
599int mailmbox_parse(struct mailmbox_folder * folder)
600{
601 int r;
602 int res;
603 size_t cur_token;
604
605 flush_uid(folder);
606
607 cur_token = 0;
608
609 r = mailmbox_parse_additionnal(folder, &cur_token);
610
611 if (r != MAILMBOX_NO_ERROR) {
612 res = r;
613 goto err;
614 }
615
616 return MAILMBOX_NO_ERROR;
617
618 err:
619 return res;
620}
diff --git a/kmicromail/libetpan/mbox/mailmbox_parse.h b/kmicromail/libetpan/mbox/mailmbox_parse.h
new file mode 100644
index 0000000..8d3d1d8
--- a/dev/null
+++ b/kmicromail/libetpan/mbox/mailmbox_parse.h
@@ -0,0 +1,56 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMBOX_PARSE_H
37
38#define MAILMBOX_PARSE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mailmbox_types.h"
45
46int mailmbox_parse(struct mailmbox_folder * folder);
47
48int
49mailmbox_parse_additionnal(struct mailmbox_folder * folder,
50 size_t * index);
51
52#ifdef __cplusplus
53}
54#endif
55
56#endif
diff --git a/kmicromail/libetpan/mbox/mailmbox_types.c b/kmicromail/libetpan/mbox/mailmbox_types.c
new file mode 100644
index 0000000..1986182
--- a/dev/null
+++ b/kmicromail/libetpan/mbox/mailmbox_types.c
@@ -0,0 +1,250 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailmbox_types.h"
37
38#include <string.h>
39#include <stdlib.h>
40
41#ifndef TRUE
42#define TRUE 1
43#endif
44
45#ifndef FALSE
46#define FALSE 0
47#endif
48
49/* *********************************************************************** */
50
51int mailmbox_msg_info_update(struct mailmbox_folder * folder,
52 size_t msg_start, size_t msg_start_len,
53 size_t msg_headers, size_t msg_headers_len,
54 size_t msg_body, size_t msg_body_len,
55 size_t msg_size, size_t msg_padding,
56 uint32_t msg_uid)
57{
58 struct mailmbox_msg_info * info;
59 int res;
60 chashdatum key;
61 chashdatum data;
62 int r;
63
64 key.data = &msg_uid;
65 key.len = sizeof(msg_uid);
66 r = chash_get(folder->mb_hash, &key, &data);
67 if (r < 0) {
68 unsigned int index;
69
70 info = mailmbox_msg_info_new(msg_start, msg_start_len,
71 msg_headers, msg_headers_len,
72 msg_body, msg_body_len, msg_size, msg_padding, msg_uid);
73 if (info == NULL) {
74 res = MAILMBOX_ERROR_MEMORY;
75 goto err;
76 }
77
78 r = carray_add(folder->mb_tab, info, &index);
79 if (r < 0) {
80 mailmbox_msg_info_free(info);
81 res = MAILMBOX_ERROR_MEMORY;
82 goto err;
83 }
84
85 if (msg_uid != 0) {
86 chashdatum key;
87 chashdatum data;
88
89 key.data = &msg_uid;
90 key.len = sizeof(msg_uid);
91 data.data = info;
92 data.len = 0;
93
94 r = chash_set(folder->mb_hash, &key, &data, NULL);
95 if (r < 0) {
96 mailmbox_msg_info_free(info);
97 carray_delete(folder->mb_tab, index);
98 res = MAILMBOX_ERROR_MEMORY;
99 goto err;
100 }
101 }
102
103 info->msg_index = index;
104 }
105 else {
106 info = data.data;
107
108 info->msg_start = msg_start;
109 info->msg_start_len = msg_start_len;
110 info->msg_headers = msg_headers;
111 info->msg_headers_len = msg_headers_len;
112 info->msg_body = msg_body;
113 info->msg_body_len = msg_body_len;
114 info->msg_size = msg_size;
115 info->msg_padding = msg_padding;
116 }
117
118 return MAILMBOX_NO_ERROR;
119
120 err:
121 return res;
122}
123
124
125struct mailmbox_msg_info *
126mailmbox_msg_info_new(size_t msg_start, size_t msg_start_len,
127 size_t msg_headers, size_t msg_headers_len,
128 size_t msg_body, size_t msg_body_len,
129 size_t msg_size, size_t msg_padding,
130 uint32_t msg_uid)
131{
132 struct mailmbox_msg_info * info;
133
134 info = malloc(sizeof(* info));
135 if (info == NULL)
136 return NULL;
137
138 info->msg_index = 0;
139 info->msg_uid = msg_uid;
140 if (msg_uid != 0)
141 info->msg_written_uid = TRUE;
142 else
143 info->msg_written_uid = FALSE;
144 info->msg_deleted = FALSE;
145
146 info->msg_start = msg_start;
147 info->msg_start_len = msg_start_len;
148
149 info->msg_headers = msg_headers;
150 info->msg_headers_len = msg_headers_len;
151
152 info->msg_body = msg_body;
153 info->msg_body_len = msg_body_len;
154
155 info->msg_size = msg_size;
156
157 info->msg_padding = msg_padding;
158
159 return info;
160}
161
162void mailmbox_msg_info_free(struct mailmbox_msg_info * info)
163{
164 free(info);
165}
166
167
168/* append info */
169
170struct mailmbox_append_info *
171mailmbox_append_info_new(const char * ai_message, size_t ai_size)
172{
173 struct mailmbox_append_info * info;
174
175 info = malloc(sizeof(* info));
176 if (info == NULL)
177 return NULL;
178
179 info->ai_message = ai_message;
180 info->ai_size = ai_size;
181
182 return info;
183}
184
185void mailmbox_append_info_free(struct mailmbox_append_info * info)
186{
187 free(info);
188}
189
190struct mailmbox_folder * mailmbox_folder_new(const char * mb_filename)
191{
192 struct mailmbox_folder * folder;
193
194 folder = malloc(sizeof(* folder));
195 if (folder == NULL)
196 goto err;
197
198 strncpy(folder->mb_filename, mb_filename, PATH_MAX);
199
200 folder->mb_mtime = (time_t) -1;
201
202 folder->mb_fd = -1;
203 folder->mb_read_only = TRUE;
204 folder->mb_no_uid = TRUE;
205
206 folder->mb_changed = FALSE;
207 folder->mb_deleted_count = 0;
208
209 folder->mb_mapping = NULL;
210 folder->mb_mapping_size = 0;
211
212 folder->mb_written_uid = 0;
213 folder->mb_max_uid = 0;
214
215 folder->mb_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY);
216 if (folder->mb_hash == NULL)
217 goto free;
218
219 folder->mb_tab = carray_new(128);
220 if (folder->mb_tab == NULL)
221 goto free_hash;
222
223 return folder;
224
225 free_hash:
226 chash_free(folder->mb_hash);
227 free:
228 free(folder);
229 err:
230 return NULL;
231}
232
233void mailmbox_folder_free(struct mailmbox_folder * folder)
234{
235 unsigned int i;
236
237 for(i = 0 ; i < carray_count(folder->mb_tab) ; i++) {
238 struct mailmbox_msg_info * info;
239
240 info = carray_get(folder->mb_tab, i);
241 if (info != NULL)
242 mailmbox_msg_info_free(info);
243 }
244
245 carray_free(folder->mb_tab);
246
247 chash_free(folder->mb_hash);
248
249 free(folder);
250}
diff --git a/kmicromail/libetpan/mbox/mailmbox_types.h b/kmicromail/libetpan/mbox/mailmbox_types.h
new file mode 100644
index 0000000..dd6758c
--- a/dev/null
+++ b/kmicromail/libetpan/mbox/mailmbox_types.h
@@ -0,0 +1,142 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMBOX_TYPES_H
37
38#define MAILMBOX_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <sys/types.h>
45
46#include <libetpan/libetpan-config.h>
47
48#include <libetpan/mailimf.h>
49#include <libetpan/carray.h>
50#include <libetpan/chash.h>
51
52enum {
53 MAILMBOX_NO_ERROR = 0,
54 MAILMBOX_ERROR_PARSE,
55 MAILMBOX_ERROR_INVAL,
56 MAILMBOX_ERROR_FILE_NOT_FOUND,
57 MAILMBOX_ERROR_MEMORY,
58 MAILMBOX_ERROR_TEMPORARY_FILE,
59 MAILMBOX_ERROR_FILE,
60 MAILMBOX_ERROR_MSG_NOT_FOUND,
61 MAILMBOX_ERROR_READONLY,
62};
63
64
65struct mailmbox_folder {
66 char mb_filename[PATH_MAX];
67
68 time_t mb_mtime;
69
70 int mb_fd;
71 int mb_read_only;
72 int mb_no_uid;
73
74 int mb_changed;
75 unsigned int mb_deleted_count;
76
77 char * mb_mapping;
78 size_t mb_mapping_size;
79
80 uint32_t mb_written_uid;
81 uint32_t mb_max_uid;
82
83 chash * mb_hash;
84 carray * mb_tab;
85};
86
87struct mailmbox_folder * mailmbox_folder_new(const char * mb_filename);
88void mailmbox_folder_free(struct mailmbox_folder * folder);
89
90
91struct mailmbox_msg_info {
92 unsigned int msg_index;
93 uint32_t msg_uid;
94 int msg_written_uid;
95 int msg_deleted;
96
97 size_t msg_start;
98 size_t msg_start_len;
99
100 size_t msg_headers;
101 size_t msg_headers_len;
102
103 size_t msg_body;
104 size_t msg_body_len;
105
106 size_t msg_size;
107
108 size_t msg_padding;
109};
110
111
112int mailmbox_msg_info_update(struct mailmbox_folder * folder,
113 size_t msg_start, size_t msg_start_len,
114 size_t msg_headers, size_t msg_headers_len,
115 size_t msg_body, size_t msg_body_len,
116 size_t msg_size, size_t msg_padding,
117 uint32_t msg_uid);
118
119struct mailmbox_msg_info *
120mailmbox_msg_info_new(size_t msg_start, size_t msg_start_len,
121 size_t msg_headers, size_t msg_headers_len,
122 size_t msg_body, size_t msg_body_len,
123 size_t msg_size, size_t msg_padding,
124 uint32_t msg_uid);
125
126void mailmbox_msg_info_free(struct mailmbox_msg_info * info);
127
128struct mailmbox_append_info {
129 const char * ai_message;
130 size_t ai_size;
131};
132
133struct mailmbox_append_info *
134mailmbox_append_info_new(const char * ai_message, size_t ai_size);
135
136void mailmbox_append_info_free(struct mailmbox_append_info * info);
137
138#ifdef __cplusplus
139}
140#endif
141
142#endif
diff --git a/kmicromail/libetpan/mh/.libs/libmailmh.a b/kmicromail/libetpan/mh/.libs/libmailmh.a
new file mode 100644
index 0000000..9e9574f
--- a/dev/null
+++ b/kmicromail/libetpan/mh/.libs/libmailmh.a
Binary files differ
diff --git a/kmicromail/libetpan/mh/mailmh.c b/kmicromail/libetpan/mh/mailmh.c
new file mode 100644
index 0000000..d6ff950
--- a/dev/null
+++ b/kmicromail/libetpan/mh/mailmh.c
@@ -0,0 +1,965 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailmh.h"
37
38/*
39perfs :
40
41/net/home/dinh/Mail/inbox/sylpheed 686
42
432724 /net/home/dinh/Mail/inbox/sylpheed
44
45bart:~/LibEtPan/libetpan/tests> time ./mhtest >/dev/null
46
47real 0m0.385s
48user 0m0.270s
49sys 0m0.110s
50
51*/
52
53#include <dirent.h>
54#include <sys/stat.h>
55#include <errno.h>
56#include <unistd.h>
57#include <sys/mman.h>
58#include <fcntl.h>
59#include <stdio.h>
60#include <stdlib.h>
61#include <string.h>
62
63#include "libetpan-config.h"
64
65struct mailmh * mailmh_new(const char * foldername)
66{
67 struct mailmh * f;
68
69 f = malloc(sizeof(*f));
70 if (f == NULL)
71 return NULL;
72
73 f->mh_main = mailmh_folder_new(NULL, foldername);
74 if (f->mh_main == NULL) {
75 free(f);
76 return NULL;
77 }
78
79 return f;
80}
81
82void mailmh_free(struct mailmh * f)
83{
84 mailmh_folder_free(f->mh_main);
85 free(f);
86}
87
88
89
90struct mailmh_msg_info * mailmh_msg_info_new(uint32_t index, size_t size,
91 time_t mtime)
92{
93 struct mailmh_msg_info * msg_info;
94
95 msg_info = malloc(sizeof(* msg_info));
96 if (msg_info == NULL)
97 return NULL;
98 msg_info->msg_index = index;
99 msg_info->msg_size = size;
100 msg_info->msg_mtime = mtime;
101
102 msg_info->msg_array_index = 0;
103
104 return msg_info;
105}
106
107void mailmh_msg_info_free(struct mailmh_msg_info * msg_info)
108{
109 free(msg_info);
110}
111
112struct mailmh_folder * mailmh_folder_new(struct mailmh_folder * parent,
113 const char * name)
114{
115 char * filename;
116 char * parent_filename;
117
118 struct mailmh_folder * folder;
119
120 folder = malloc(sizeof(* folder));
121 if (folder == NULL)
122 goto err;
123
124 if (parent == NULL) {
125 filename = strdup(name);
126 if (filename == NULL)
127 goto free_folder;
128 }
129 else {
130 parent_filename = parent->fl_filename;
131 filename = malloc(strlen(parent_filename) + strlen(name) + 2);
132 if (filename == NULL)
133 goto free_folder;
134
135 strcpy(filename, parent_filename);
136 strcat(filename, MAIL_DIR_SEPARATOR_S);
137 strcat(filename, name);
138 }
139
140 folder->fl_filename = filename;
141
142 folder->fl_name = strdup(name);
143 if (folder->fl_name == NULL)
144 goto free_filename;
145
146 folder->fl_msgs_tab = carray_new(128);
147 if (folder->fl_msgs_tab == NULL)
148 goto free_name;
149
150#if 0
151 folder->fl_msgs_hash = cinthash_new(128);
152 if (folder->fl_msgs_hash == NULL)
153 goto free_msgs_tab;
154#endif
155 folder->fl_msgs_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY);
156 if (folder->fl_msgs_hash == NULL)
157 goto free_msgs_tab;
158
159 folder->fl_subfolders_tab = carray_new(128);
160 if (folder->fl_subfolders_tab == NULL)
161 goto free_msgs_hash;
162
163 folder->fl_subfolders_hash = chash_new(128, CHASH_COPYNONE);
164 if (folder->fl_subfolders_hash == NULL)
165 goto free_subfolders_tab;
166
167 folder->fl_mtime = 0;
168 folder->fl_parent = parent;
169 folder->fl_max_index = 0;
170
171 return folder;
172
173 free_subfolders_tab:
174 carray_free(folder->fl_subfolders_tab);
175 free_msgs_hash:
176#if 0
177 cinthash_free(folder->fl_msgs_hash);
178#endif
179 chash_free(folder->fl_msgs_hash);
180 free_msgs_tab:
181 carray_free(folder->fl_msgs_tab);
182 free_name:
183 free(folder->fl_name);
184 free_filename:
185 free(folder->fl_filename);
186 free_folder:
187 free(folder);
188 err:
189 return NULL;
190}
191
192void mailmh_folder_free(struct mailmh_folder * folder)
193{
194 unsigned int i;
195
196 for(i = 0 ; i < carray_count(folder->fl_subfolders_tab) ; i++) {
197 struct mailmh_folder * subfolder;
198
199 subfolder = carray_get(folder->fl_subfolders_tab, i);
200 if (subfolder != NULL)
201 mailmh_folder_free(subfolder);
202 }
203 carray_free(folder->fl_subfolders_tab);
204 chash_free(folder->fl_subfolders_hash);
205
206 for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) {
207 struct mailmh_msg_info * msg_info;
208
209 msg_info = carray_get(folder->fl_msgs_tab, i);
210 if (msg_info != NULL)
211 mailmh_msg_info_free(msg_info);
212 }
213 carray_free(folder->fl_msgs_tab);
214 chash_free(folder->fl_msgs_hash);
215#if 0
216 cinthash_free(folder->fl_msgs_hash);
217#endif
218
219 free(folder->fl_filename);
220 free(folder->fl_name);
221
222 free(folder);
223}
224
225struct mailmh_folder * mailmh_folder_find(struct mailmh_folder * root,
226 const char * filename)
227{
228 int r;
229 char pathname[PATH_MAX];
230 char * p;
231 chashdatum key;
232 chashdatum data;
233 struct mailmh_folder * folder;
234 char * start;
235
236 if (strcmp(root->fl_filename, filename) == 0)
237 return root;
238
239#if 0
240 r = mailmh_folder_update(root);
241 if (r != MAILMH_NO_ERROR)
242 return NULL;
243#endif
244
245#if 0
246 for(i = 0 ; i < root->fl_subfolders_tab->len ; i++) {
247 struct mailmh_folder * subfolder;
248
249 subfolder = carray_get(root->fl_subfolders_tab, i);
250 if (subfolder != NULL)
251 if (strncmp(subfolder->fl_filename, filename,
252 strlen(subfolder->fl_filename)) == 0)
253 return mailmh_folder_find(subfolder, filename);
254 }
255#endif
256 strncpy(pathname, filename, PATH_MAX);
257 pathname[PATH_MAX - 1] = 0;
258 start = pathname + strlen(root->fl_filename) + 1;
259
260 p = strchr(start, MAIL_DIR_SEPARATOR);
261 if (p != NULL) {
262 * p = 0;
263
264 root = mailmh_folder_find(root, pathname);
265 if (root != NULL) {
266 folder = mailmh_folder_find(root, filename);
267 if (folder == NULL)
268 return NULL;
269 return folder;
270 }
271
272 return NULL;
273 }
274 else {
275 key.data = pathname;
276 key.len = strlen(pathname);
277 r = chash_get(root->fl_subfolders_hash, &key, &data);
278 if (r < 0)
279 return NULL;
280
281 return data.data;
282 }
283}
284
285int mailmh_folder_update(struct mailmh_folder * folder)
286{
287 DIR * d;
288 struct dirent * ent;
289 struct stat buf;
290 char * mh_seq;
291 char filename[PATH_MAX];
292 int res;
293 int r;
294 uint32_t max_index;
295#if 0
296 int add_folder;
297#endif
298 unsigned int i;
299
300 if (stat(folder->fl_filename, &buf) == -1) {
301 res = MAILMH_ERROR_FOLDER;
302 goto err;
303 }
304
305 if (folder->fl_mtime == buf.st_mtime) {
306 res = MAILMH_NO_ERROR;
307 goto err;
308 }
309
310 folder->fl_mtime = buf.st_mtime;
311
312 d = opendir(folder->fl_filename);
313 if (d == NULL) {
314 res = MAILMH_ERROR_FOLDER;
315 goto err;
316 }
317
318 max_index = 0;
319
320#if 0
321 if (folder->fl_subfolders_tab->len == 0)
322 add_folder = 1;
323 else
324 add_folder = 0;
325#endif
326
327 /* clear the message list */
328
329 for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) {
330 struct mailmh_msg_info * msg_info;
331 chashdatum key;
332
333 msg_info = carray_get(folder->fl_msgs_tab, i);
334 if (msg_info == NULL)
335 continue;
336
337#if 0
338 cinthash_remove(folder->fl_msgs_hash, msg_info->msg_index);
339#endif
340 key.data = &msg_info->msg_index;
341 key.len = sizeof(msg_info->msg_index);
342 chash_delete(folder->fl_msgs_hash, &key, NULL);
343
344 mailmh_msg_info_free(msg_info);
345 }
346
347 carray_set_size(folder->fl_msgs_tab, 0);
348
349 do {
350 uint32_t index;
351
352 ent = readdir(d);
353
354 if (ent != NULL) {
355
356 snprintf(filename, PATH_MAX,
357 "%s%c%s", folder->fl_filename, MAIL_DIR_SEPARATOR, ent->d_name);
358
359 if (stat(filename, &buf) == -1)
360 continue;
361
362 if (S_ISREG(buf.st_mode)) {
363 index = strtoul(ent->d_name, NULL, 10);
364 if (index != 0) {
365 struct mailmh_msg_info * msg_info;
366 unsigned int array_index;
367 chashdatum key;
368 chashdatum data;
369
370 msg_info = mailmh_msg_info_new(index, buf.st_size, buf.st_mtime);
371 if (msg_info == NULL) {
372 res = MAILMH_ERROR_MEMORY;
373 goto closedir;
374 }
375
376 r = carray_add(folder->fl_msgs_tab, msg_info, &array_index);
377 if (r < 0) {
378 mailmh_msg_info_free(msg_info);
379 res = MAILMH_ERROR_MEMORY;
380 goto closedir;
381 }
382 msg_info->msg_array_index = array_index;
383
384 if (index > max_index)
385 max_index = index;
386
387#if 0
388 r = cinthash_add(folder->fl_msgs_hash, msg_info->msg_index, msg_info);
389#endif
390 key.data = &msg_info->msg_index;
391 key.len = sizeof(msg_info->msg_index);
392 data.data = msg_info;
393 data.len = 0;
394
395 r = chash_set(folder->fl_msgs_hash, &key, &data, NULL);
396 if (r < 0) {
397 carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index);
398 mailmh_msg_info_free(msg_info);
399 res = MAILMH_ERROR_MEMORY;
400 goto closedir;
401 }
402 }
403 }
404 else if (S_ISDIR(buf.st_mode)) {
405 struct mailmh_folder * subfolder;
406 unsigned int array_index;
407 chashdatum key;
408 chashdatum data;
409
410 if (ent->d_name[0] == '.') {
411 if (ent->d_name[1] == 0)
412 continue;
413 if ((ent->d_name[1] == '.') && (ent->d_name[2] == 0))
414 continue;
415 }
416
417 key.data = ent->d_name;
418 key.len = strlen(ent->d_name);
419 r = chash_get(folder->fl_subfolders_hash, &key, &data);
420 if (r < 0) {
421 subfolder = mailmh_folder_new(folder, ent->d_name);
422 if (subfolder == NULL) {
423 res = MAILMH_ERROR_MEMORY;
424 goto closedir;
425 }
426
427 r = carray_add(folder->fl_subfolders_tab, subfolder, &array_index);
428 if (r < 0) {
429 mailmh_folder_free(subfolder);
430 res = MAILMH_ERROR_MEMORY;
431 goto closedir;
432 }
433 subfolder->fl_array_index = array_index;
434
435 key.data = subfolder->fl_filename;
436 key.len = strlen(subfolder->fl_filename);
437 data.data = subfolder;
438 data.len = 0;
439 r = chash_set(folder->fl_subfolders_hash, &key, &data, NULL);
440 if (r < 0) {
441 carray_delete_fast(folder->fl_subfolders_tab, subfolder->fl_array_index);
442 mailmh_folder_free(subfolder);
443 res = MAILMH_ERROR_MEMORY;
444 goto closedir;
445 }
446 }
447 }
448 }
449 }
450 while (ent != NULL);
451
452 folder->fl_max_index = max_index;
453
454 mh_seq = malloc(strlen(folder->fl_filename) + 2 + sizeof(".mh_sequences"));
455 if (mh_seq == NULL) {
456 res = MAILMH_ERROR_MEMORY;
457 goto closedir;
458 }
459 strcpy(mh_seq, folder->fl_filename);
460 strcat(mh_seq, MAIL_DIR_SEPARATOR_S);
461 strcat(mh_seq, ".mh_sequences");
462
463 if (stat(mh_seq, &buf) == -1) {
464 int fd;
465
466 fd = creat(mh_seq, S_IRUSR | S_IWUSR);
467 if (fd != -1)
468 close(fd);
469 }
470 free(mh_seq);
471
472 closedir(d);
473
474 return MAILMH_NO_ERROR;
475
476 closedir:
477 closedir(d);
478 err:
479 return res;
480}
481
482int mailmh_folder_add_subfolder(struct mailmh_folder * parent,
483 const char * name)
484{
485 char * foldername;
486 int r;
487 struct mailmh_folder * folder;
488 unsigned int array_index;
489 chashdatum key;
490 chashdatum data;
491
492 foldername = malloc(strlen(parent->fl_filename) + strlen(name) + 2);
493 if (foldername == NULL)
494 return MAILMH_ERROR_MEMORY;
495 strcpy(foldername, parent->fl_filename);
496 strcat(foldername, MAIL_DIR_SEPARATOR_S);
497 strcat(foldername, name);
498
499 r = mkdir(foldername, 0700);
500 free(foldername);
501
502 if (r < 0)
503 return MAILMH_ERROR_FOLDER;
504
505 folder = mailmh_folder_new(parent, name);
506 if (folder == NULL)
507 return MAILMH_ERROR_MEMORY;
508
509 r = carray_add(parent->fl_subfolders_tab, folder, &array_index);
510 if (r < 0) {
511 mailmh_folder_free(folder);
512 return MAILMH_ERROR_MEMORY;
513 }
514 folder->fl_array_index = array_index;
515
516 key.data = folder->fl_filename;
517 key.len = strlen(folder->fl_filename);
518 data.data = folder;
519 data.len = 0;
520
521 r = chash_set(parent->fl_subfolders_hash, &key, &data, NULL);
522 if (r < 0) {
523 carray_delete_fast(folder->fl_subfolders_tab, folder->fl_array_index);
524 mailmh_folder_free(folder);
525 return MAILMH_ERROR_MEMORY;
526 }
527
528 return MAILMH_NO_ERROR;
529}
530
531int mailmh_folder_remove_subfolder(struct mailmh_folder * folder)
532{
533 struct mailmh_folder * parent;
534 chashdatum key;
535 chashdatum data;
536 int r;
537
538 parent = folder->fl_parent;
539
540 key.data = folder->fl_filename;
541 key.len = strlen(folder->fl_filename);
542
543 r = chash_get(parent->fl_subfolders_hash, &key, &data);
544 if (r < 0)
545 return MAILMH_ERROR_FOLDER;
546
547 chash_delete(parent->fl_subfolders_hash, &key, NULL);
548 carray_delete_fast(parent->fl_subfolders_tab, folder->fl_array_index);
549
550 mailmh_folder_free(folder);
551
552 return MAILMH_NO_ERROR;
553
554}
555
556int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder,
557 struct mailmh_folder * dst_folder,
558 const char * new_name)
559{
560 int r;
561 struct mailmh_folder * folder;
562 struct mailmh_folder * parent;
563 char * new_foldername;
564
565 parent = src_folder->fl_parent;
566 if (parent == NULL)
567 return MAILMH_ERROR_RENAME;
568
569 new_foldername = malloc(strlen(dst_folder->fl_filename) + 2 + strlen(new_name));
570 if (new_foldername == NULL)
571 return MAILMH_ERROR_MEMORY;
572
573 strcpy(new_foldername, dst_folder->fl_filename);
574 strcat(new_foldername, MAIL_DIR_SEPARATOR_S);
575 strcat(new_foldername, new_name);
576
577 r = rename(src_folder->fl_filename, new_foldername);
578 free(new_foldername);
579 if (r < 0)
580 return MAILMH_ERROR_RENAME;
581
582 r = mailmh_folder_remove_subfolder(src_folder);
583 if (r != MAILMH_NO_ERROR)
584 return r;
585
586 folder = mailmh_folder_new(dst_folder, new_name);
587 if (folder == NULL)
588 return MAILMH_ERROR_MEMORY;
589
590 r = carray_add(parent->fl_subfolders_tab, folder, NULL);
591 if (r < 0) {
592 mailmh_folder_free(folder);
593 return MAILMH_ERROR_MEMORY;
594 }
595
596 return MAILMH_NO_ERROR;
597}
598
599#define MAX_TRY_ALLOC 32
600
601/* initial file MUST be in the same directory */
602
603static int mailmh_folder_alloc_msg(struct mailmh_folder * folder,
604 char * filename, uint32_t * result)
605{
606 uint32_t max;
607 uint32_t k;
608 char * new_filename;
609 size_t len;
610
611 len = strlen(folder->fl_filename) + 20;
612 new_filename = malloc(len);
613 if (new_filename == NULL)
614 return MAILMH_ERROR_MEMORY;
615
616 max = folder->fl_max_index + 1;
617
618 k = 0;
619 while (k < MAX_TRY_ALLOC) {
620 snprintf(new_filename, len, "%s%c%lu", folder->fl_filename,
621 MAIL_DIR_SEPARATOR, (unsigned long) (max + k));
622
623 if (link(filename, new_filename) == 0) {
624 int r;
625
626 free(new_filename);
627 unlink(filename);
628
629 if (k > MAX_TRY_ALLOC / 2) {
630 r = mailmh_folder_update(folder);
631 /* ignore errors */
632 }
633
634 * result = max + k;
635
636 folder->fl_max_index = max + k;
637
638 return MAILMH_NO_ERROR;
639 }
640 else if (errno == EXDEV) {
641 free(filename);
642 return MAILMH_ERROR_FOLDER;
643 }
644 k ++;
645 }
646
647 free(new_filename);
648
649 return MAILMH_ERROR_FOLDER;
650}
651
652int mailmh_folder_get_message_filename(struct mailmh_folder * folder,
653 uint32_t index, char ** result)
654{
655 char * filename;
656 int len;
657
658#if 0
659 r = mailmh_folder_update(folder);
660 if (r != MAILMH_NO_ERROR)
661 return r;
662#endif
663
664 len = strlen(folder->fl_filename) + 20;
665 filename = malloc(len);
666 if (filename == NULL)
667 return MAILMH_ERROR_MEMORY;
668
669 snprintf(filename, len, "%s%c%lu", folder->fl_filename, MAIL_DIR_SEPARATOR,
670 (unsigned long) index);
671
672 * result = filename;
673
674 return MAILMH_NO_ERROR;;
675}
676
677
678int mailmh_folder_get_message_fd(struct mailmh_folder * folder,
679 uint32_t index, int flags, int * result)
680{
681 char * filename;
682 int fd;
683 int r;
684
685#if 0
686 r = mailmh_folder_update(folder);
687 if (r != MAILMH_NO_ERROR)
688 return r;
689#endif
690
691 r = mailmh_folder_get_message_filename(folder, index, &filename);
692 if (r != MAILMH_NO_ERROR)
693 return r;
694
695 fd = open(filename, flags);
696 free(filename);
697 if (fd == -1)
698 return MAILMH_ERROR_MSG_NOT_FOUND;
699
700 * result = fd;
701
702 return MAILMH_NO_ERROR;
703}
704
705int mailmh_folder_get_message_size(struct mailmh_folder * folder,
706 uint32_t index, size_t * result)
707{
708 int r;
709 char * filename;
710 struct stat buf;
711
712 r = mailmh_folder_get_message_filename(folder, index, &filename);
713 if (r != MAILMH_NO_ERROR)
714 return r;
715
716 r = stat(filename, &buf);
717 free(filename);
718 if (r < 0)
719 return MAILMH_ERROR_FILE;
720
721 * result = buf.st_size;
722
723 return MAILMH_NO_ERROR;
724}
725
726int mailmh_folder_add_message(struct mailmh_folder * folder,
727 const char * message, size_t size)
728{
729 char * tmpname;
730 int fd;
731 size_t namesize;
732 size_t left;
733 ssize_t res;
734 struct mailmh_msg_info * msg_info;
735 uint32_t index;
736 int error;
737 int r;
738 unsigned int array_index;
739 struct stat buf;
740 chashdatum key;
741 chashdatum data;
742
743#if 0
744 r = mailmh_folder_update(folder);
745 if (r != MAILMH_NO_ERROR) {
746 error = r;
747 goto err;
748 }
749#endif
750
751 namesize = strlen(folder->fl_filename) + 20;
752 tmpname = malloc(namesize);
753 snprintf(tmpname, namesize, "%s%ctmpXXXXXX",
754 folder->fl_filename, MAIL_DIR_SEPARATOR);
755 fd = mkstemp(tmpname);
756 if (fd < 0) {
757 error = MAILMH_ERROR_FILE;
758 goto free;
759 }
760
761 left = size;
762 while (left > 0) {
763 res = write(fd, message, left);
764 if (res == -1) {
765 close(fd);
766 error = MAILMH_ERROR_FILE;
767 goto free;
768 }
769
770 left -= res;
771 }
772 close(fd);
773
774 r = stat(tmpname, &buf);
775 if (r < 0) {
776 error = MAILMH_ERROR_FILE;
777 goto free;
778 }
779
780 r = mailmh_folder_alloc_msg(folder, tmpname, &index);
781 if (r != MAILMH_NO_ERROR) {
782 unlink(tmpname);
783 error = MAILMH_ERROR_COULD_NOT_ALLOC_MSG;
784 goto free;
785 }
786 free(tmpname);
787
788 msg_info = mailmh_msg_info_new(index, size, buf.st_mtime);
789 if (msg_info == NULL) {
790 mailmh_folder_remove_message(folder, index);
791 error = MAILMH_ERROR_MEMORY;
792 goto err;
793 }
794
795 r = carray_add(folder->fl_msgs_tab, msg_info, &array_index);
796 if (r < 0) {
797 mailmh_folder_remove_message(folder, index);
798 mailmh_msg_info_free(msg_info);
799 error = MAILMH_ERROR_MEMORY;
800 goto err;
801 }
802 msg_info->msg_array_index = array_index;
803
804#if 0
805 r = cinthash_add(folder->fl_msgs_hash, index, msg_info);
806#endif
807 key.data = &index;
808 key.len = sizeof(index);
809 data.data = msg_info;
810 data.len = 0;
811
812 r = chash_set(folder->fl_msgs_hash, &key, &data, NULL);
813 if (r < 0) {
814 carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index);
815 mailmh_msg_info_free(msg_info);
816 error = MAILMH_ERROR_MEMORY;
817 goto err;
818 }
819
820 return MAILMH_NO_ERROR;
821
822 free:
823 free(tmpname);
824 err:
825 return error;
826}
827
828int mailmh_folder_add_message_file(struct mailmh_folder * folder,
829 int fd)
830{
831 char * message;
832 struct stat buf;
833 int r;
834
835#if 0
836 r = mailmh_folder_update(folder);
837 if (r != MAILMH_NO_ERROR)
838 return r;
839#endif
840
841 if (fstat(fd, &buf) == -1)
842 return MAILMH_ERROR_FILE;
843
844 message = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
845 if (message == MAP_FAILED)
846 return MAILMH_ERROR_FILE;
847
848 r = mailmh_folder_add_message(folder, message, buf.st_size);
849
850 munmap(message, buf.st_size);
851
852 return r;
853}
854
855int mailmh_folder_remove_message(struct mailmh_folder * folder,
856 uint32_t index)
857{
858 char * filename;
859 struct mailmh_msg_info * msg_info;
860 int res;
861 int r;
862 chashdatum key;
863 chashdatum data;
864
865#if 0
866 r = mailmh_folder_update(folder);
867 if (r != MAILMH_NO_ERROR) {
868 res = r;
869 goto err;
870 }
871#endif
872
873 r = mailmh_folder_get_message_filename(folder, index, &filename);
874 if (filename == NULL) {
875 res = r;
876 goto err;
877 }
878
879 if (unlink(filename) == -1) {
880 res = MAILMH_ERROR_FILE;
881 goto free;
882 }
883
884 key.data = &index;
885 key.len = sizeof(index);
886 r = chash_get(folder->fl_msgs_hash, &key, &data);
887#if 0
888 msg_info = cinthash_find(folder->fl_msgs_hash, index);
889#endif
890 if (r == 0) {
891 msg_info = data.data;
892
893 carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index);
894#if 0
895 cinthash_remove(folder->fl_msgs_hash, index);
896#endif
897 chash_delete(folder->fl_msgs_hash, &key, NULL);
898 }
899
900 return MAILMH_NO_ERROR;
901
902 free:
903 free(filename);
904 err:
905 return res;
906}
907
908
909int mailmh_folder_move_message(struct mailmh_folder * dest_folder,
910 struct mailmh_folder * src_folder,
911 uint32_t index)
912{
913 int fd;
914 char * filename;
915 int r;
916
917#if 0
918 r = mailmh_folder_update(dest_folder);
919 if (r != MAILMH_NO_ERROR)
920 return r;
921 r = mailmh_folder_update(src_folder);
922 if (r != MAILMH_NO_ERROR)
923 return r;
924#endif
925
926 /* move on the same filesystem */
927 r = mailmh_folder_get_message_filename(src_folder, index, &filename);
928 if (r != MAILMH_NO_ERROR)
929 return r;
930
931 r = mailmh_folder_alloc_msg(dest_folder, filename, &index);
932 free(filename);
933 if (r == MAILMH_NO_ERROR)
934 return MAILMH_NO_ERROR;
935
936 /* move on the different filesystems */
937 r = mailmh_folder_get_message_fd(src_folder, index, O_RDONLY, &fd);
938 if (r != MAILMH_NO_ERROR)
939 return r;
940
941 r = mailmh_folder_add_message_file(dest_folder, fd);
942 if (r != MAILMH_NO_ERROR) {
943 close(fd);
944 return r;
945 }
946
947 close(fd);
948
949 r = mailmh_folder_remove_message(src_folder, index);
950
951 return MAILMH_NO_ERROR;
952}
953
954unsigned int mailmh_folder_get_message_number(struct mailmh_folder * folder)
955{
956 unsigned int i;
957 unsigned int count;
958
959 count = 0;
960 for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++)
961 if (carray_get(folder->fl_msgs_tab, i) != NULL)
962 count ++;
963
964 return count;
965}
diff --git a/kmicromail/libetpan/mh/mailmh.h b/kmicromail/libetpan/mh/mailmh.h
new file mode 100644
index 0000000..40432cb
--- a/dev/null
+++ b/kmicromail/libetpan/mh/mailmh.h
@@ -0,0 +1,143 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMH_H
37
38#define MAILMH_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <sys/types.h>
45#include <inttypes.h>
46#include <libetpan/carray.h>
47#include <libetpan/cinthash.h>
48#include <libetpan/chash.h>
49
50enum {
51 MAILMH_NO_ERROR = 0,
52 MAILMH_ERROR_FOLDER,
53 MAILMH_ERROR_MEMORY,
54 MAILMH_ERROR_FILE,
55 MAILMH_ERROR_COULD_NOT_ALLOC_MSG,
56 MAILMH_ERROR_RENAME,
57 MAILMH_ERROR_MSG_NOT_FOUND,
58};
59
60struct mailmh {
61 struct mailmh_folder * mh_main;
62};
63
64struct mailmh_msg_info {
65 unsigned int msg_array_index;
66 uint32_t msg_index;
67 size_t msg_size;
68 time_t msg_mtime;
69};
70
71struct mailmh_folder {
72 char * fl_filename;
73 unsigned int fl_array_index;
74
75 char * fl_name;
76 time_t fl_mtime;
77 struct mailmh_folder * fl_parent;
78 uint32_t fl_max_index;
79
80 carray * fl_msgs_tab;
81#if 0
82 cinthash_t * fl_msgs_hash;
83#endif
84 chash * fl_msgs_hash;
85
86 carray * fl_subfolders_tab;
87 chash * fl_subfolders_hash;
88};
89
90struct mailmh * mailmh_new(const char * foldername);
91void mailmh_free(struct mailmh * f);
92
93struct mailmh_msg_info *
94mailmh_msg_info_new(uint32_t index, size_t size, time_t mtime);
95void mailmh_msg_info_free(struct mailmh_msg_info * msg_info);
96
97struct mailmh_folder * mailmh_folder_new(struct mailmh_folder * parent,
98 const char * name);
99void mailmh_folder_free(struct mailmh_folder * folder);
100
101int mailmh_folder_add_subfolder(struct mailmh_folder * parent,
102 const char * name);
103
104struct mailmh_folder * mailmh_folder_find(struct mailmh_folder * root,
105 const char * filename);
106
107int mailmh_folder_remove_subfolder(struct mailmh_folder * folder);
108
109int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder,
110 struct mailmh_folder * dst_folder,
111 const char * new_name);
112
113int mailmh_folder_get_message_filename(struct mailmh_folder * folder,
114 uint32_t index, char ** result);
115
116int mailmh_folder_get_message_fd(struct mailmh_folder * folder,
117 uint32_t index, int flags, int * result);
118
119int mailmh_folder_get_message_size(struct mailmh_folder * folder,
120 uint32_t index, size_t * result);
121
122int mailmh_folder_add_message(struct mailmh_folder * folder,
123 const char * message, size_t size);
124
125int mailmh_folder_add_message_file(struct mailmh_folder * folder,
126 int fd);
127
128int mailmh_folder_remove_message(struct mailmh_folder * folder,
129 uint32_t index);
130
131int mailmh_folder_move_message(struct mailmh_folder * dest_folder,
132 struct mailmh_folder * src_folder,
133 uint32_t index);
134
135int mailmh_folder_update(struct mailmh_folder * folder);
136
137unsigned int mailmh_folder_get_message_number(struct mailmh_folder * folder);
138
139#ifdef __cplusplus
140}
141#endif
142
143#endif
diff --git a/kmicromail/libetpan/mime/.libs/libmailmime.a b/kmicromail/libetpan/mime/.libs/libmailmime.a
new file mode 100644
index 0000000..902b9d9
--- a/dev/null
+++ b/kmicromail/libetpan/mime/.libs/libmailmime.a
Binary files differ
diff --git a/kmicromail/libetpan/mime/TODO b/kmicromail/libetpan/mime/TODO
new file mode 100644
index 0000000..df02810
--- a/dev/null
+++ b/kmicromail/libetpan/mime/TODO
@@ -0,0 +1,10 @@
1- see about the RFC2047, beginning in mailmime_decode.[ch]
2- content-langage
3- single mime_field
4- RFC 2048
5- RFC 2049
6- RFC 2231
7- RFC 2387
8- RFC 2424
9- RFC 2557
10
diff --git a/kmicromail/libetpan/mime/mailmime.c b/kmicromail/libetpan/mime/mailmime.c
new file mode 100644
index 0000000..e920722
--- a/dev/null
+++ b/kmicromail/libetpan/mime/mailmime.c
@@ -0,0 +1,1408 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailmime.h"
37
38/*
39 RFC 2045
40 RFC 2046
41 RFC 2047
42 RFC 2048
43 RFC 2049
44 RFC 2231
45 RFC 2387
46 RFC 2424
47 RFC 2557
48
49 RFC 2183 Content-Disposition
50
51 RFC 1766 Language
52 */
53
54#include <ctype.h>
55#include <stdlib.h>
56#include <string.h>
57
58#include "mailmime_types.h"
59#include "mailmime_disposition.h"
60#include "mailimf.h"
61
62#ifndef TRUE
63#define TRUE 1
64#endif
65
66#ifndef FALSE
67#define FALSE 0
68#endif
69
70static int mailmime_attribute_parse(const char * message, size_t length,
71 size_t * index,
72 char ** result);
73static int
74mailmime_composite_type_parse(const char * message, size_t length,
75 size_t * index,
76 struct mailmime_composite_type ** result);
77
78static int is_text(char ch);
79
80static int
81mailmime_discrete_type_parse(const char * message, size_t length,
82 size_t * index,
83 struct mailmime_discrete_type ** result);
84
85static int mailmime_mechanism_parse(const char * message, size_t length,
86 size_t * index,
87 struct mailmime_mechanism ** result);
88
89static int mailmime_subtype_parse(const char * message, size_t length,
90 size_t * index, char ** result);
91
92static int is_token(char ch);
93
94static int mailmime_token_parse(const char * message, size_t length,
95 size_t * index,
96 char ** token);
97
98static int is_tspecials(char ch);
99
100static int mailmime_type_parse(const char * message, size_t length,
101 size_t * index,
102 struct mailmime_type ** result);
103
104/*
105int mailmime_version_parse(const char * message, guint32 length,
106 guint32 * index,
107 guint32 * result);
108*/
109
110/*
111static gboolean mailmime_x_token_parse(gconst char * message, guint32 length,
112 guint32 * index,
113 gchar ** result);
114*/
115
116/* ********************************************************************** */
117
118/*
119x attribute := token
120 ; Matching of attributes
121 ; is ALWAYS case-insensitive.
122*/
123
124static int mailmime_attribute_parse(const char * message, size_t length,
125 size_t * index,
126 char ** result)
127{
128 return mailmime_token_parse(message, length, index, result);
129}
130
131/*
132x composite-type := "message" / "multipart" / extension-token
133*/
134
135static int
136mailmime_composite_type_parse(const char * message, size_t length,
137 size_t * index,
138 struct mailmime_composite_type ** result)
139{
140 char * extension_token;
141 int type;
142 struct mailmime_composite_type * ct;
143 size_t cur_token;
144 int r;
145 int res;
146
147 cur_token = * index;
148
149 extension_token = NULL;
150
151 type = MAILMIME_COMPOSITE_TYPE_ERROR; /* XXX - removes a gcc warning */
152
153 r = mailimf_token_case_insensitive_parse(message, length,
154 &cur_token, "message");
155 if (r == MAILIMF_NO_ERROR)
156 type = MAILMIME_COMPOSITE_TYPE_MESSAGE;
157
158 if (r == MAILIMF_ERROR_PARSE) {
159 r = mailimf_token_case_insensitive_parse(message, length,
160 &cur_token, "multipart");
161 if (r == MAILIMF_NO_ERROR)
162 type = MAILMIME_COMPOSITE_TYPE_MULTIPART;
163 }
164
165 if (r != MAILIMF_NO_ERROR) {
166 res = r;
167 goto err;
168 }
169
170 ct = mailmime_composite_type_new(type, extension_token);
171 if (ct == NULL) {
172 res = MAILIMF_ERROR_MEMORY;
173 goto free_extension;
174 }
175
176 * result = ct;
177 * index = cur_token;
178
179 return MAILIMF_NO_ERROR;
180
181 free_extension:
182 if (extension_token != NULL)
183 mailmime_extension_token_free(extension_token);
184 err:
185 return res;
186}
187
188/*
189x content := "Content-Type" ":" type "/" subtype
190 *(";" parameter)
191 ; Matching of media type and subtype
192 ; is ALWAYS case-insensitive.
193*/
194
195int mailmime_content_parse(const char * message, size_t length,
196 size_t * index,
197 struct mailmime_content ** result)
198{
199 size_t cur_token;
200 struct mailmime_type * type;
201 char * subtype;
202 clist * parameters_list;
203 struct mailmime_content * content;
204 int r;
205 int res;
206
207 cur_token = * index;
208
209 mailimf_cfws_parse(message, length, &cur_token);
210
211 r = mailmime_type_parse(message, length, &cur_token, &type);
212 if (r != MAILIMF_NO_ERROR) {
213 res = r;
214 goto err;
215 }
216
217 r = mailimf_unstrict_char_parse(message, length, &cur_token, '/');
218 switch (r) {
219 case MAILIMF_NO_ERROR:
220 r = mailimf_cfws_parse(message, length, &cur_token);
221 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
222 res = r;
223 goto free_type;
224 }
225
226 r = mailmime_subtype_parse(message, length, &cur_token, &subtype);
227 if (r != MAILIMF_NO_ERROR) {
228 res = r;
229 goto free_type;
230 }
231 break;
232
233 case MAILIMF_ERROR_PARSE:
234 subtype = strdup("unknown");
235 break;
236
237 default:
238 res = r;
239 goto free_type;
240 }
241
242 parameters_list = clist_new();
243 if (parameters_list == NULL) {
244 res = MAILIMF_ERROR_MEMORY;
245 goto free_type;
246 }
247
248 while (1) {
249 size_t final_token;
250 struct mailmime_parameter * parameter;
251
252 final_token = cur_token;
253 r = mailimf_unstrict_char_parse(message, length, &cur_token, ';');
254 if (r != MAILIMF_NO_ERROR) {
255 cur_token = final_token;
256 break;
257 }
258
259 r = mailimf_cfws_parse(message, length, &cur_token);
260 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
261 res = r;
262 goto free_type;
263 }
264
265 r = mailmime_parameter_parse(message, length, &cur_token, &parameter);
266 if (r == MAILIMF_NO_ERROR) {
267 /* do nothing */
268 }
269 else if (r == MAILIMF_ERROR_PARSE) {
270 cur_token = final_token;
271 break;
272 }
273 else {
274 res = r;
275 goto err;
276 }
277
278 r = clist_append(parameters_list, parameter);
279 if (r < 0) {
280 mailmime_parameter_free(parameter);
281 res = MAILIMF_ERROR_MEMORY;
282 goto free_parameters;
283 }
284 }
285
286 content = mailmime_content_new(type, subtype, parameters_list);
287 if (content == NULL) {
288 res = MAILIMF_ERROR_MEMORY;
289 goto free_parameters;
290 }
291
292 * result = content;
293 * index = cur_token;
294
295 return MAILIMF_NO_ERROR;
296
297 free_parameters:
298 clist_foreach(parameters_list, (clist_func) mailmime_parameter_free, NULL);
299 clist_free(parameters_list);
300
301 mailmime_subtype_free(subtype);
302 free_type:
303 mailmime_type_free(type);
304 err:
305 return res;
306}
307
308/*
309x description := "Content-Description" ":" *text
310*/
311
312static int is_text(char ch)
313{
314 unsigned char uch = (unsigned char) ch;
315
316 if (uch < 1)
317 return FALSE;
318
319 if ((uch == 10) || (uch == 13))
320 return FALSE;
321
322 return TRUE;
323}
324
325int mailmime_description_parse(const char * message, size_t length,
326 size_t * index,
327 char ** result)
328{
329 return mailimf_custom_string_parse(message, length,
330 index, result,
331 is_text);
332}
333
334/*
335x discrete-type := "text" / "image" / "audio" / "video" /
336 "application" / extension-token
337*/
338
339/* currently porting */
340
341static int
342mailmime_discrete_type_parse(const char * message, size_t length,
343 size_t * index,
344 struct mailmime_discrete_type ** result)
345{
346 char * extension;
347 int type;
348 struct mailmime_discrete_type * discrete_type;
349 size_t cur_token;
350 int r;
351 int res;
352
353 cur_token = * index;
354
355 extension = NULL;
356
357 type = MAILMIME_DISCRETE_TYPE_ERROR; /* XXX - removes a gcc warning */
358
359 r = mailimf_token_case_insensitive_parse(message, length,
360 &cur_token, "text");
361 if (r == MAILIMF_NO_ERROR)
362 type = MAILMIME_DISCRETE_TYPE_TEXT;
363
364 if (r == MAILIMF_ERROR_PARSE) {
365 r = mailimf_token_case_insensitive_parse(message, length,
366 &cur_token, "image");
367 if (r == MAILIMF_NO_ERROR)
368 type = MAILMIME_DISCRETE_TYPE_IMAGE;
369 }
370
371 if (r == MAILIMF_ERROR_PARSE) {
372 r = mailimf_token_case_insensitive_parse(message, length,
373 &cur_token, "audio");
374 if (r == MAILIMF_NO_ERROR)
375 type = MAILMIME_DISCRETE_TYPE_AUDIO;
376 }
377
378 if (r == MAILIMF_ERROR_PARSE) {
379 r = mailimf_token_case_insensitive_parse(message, length,
380 &cur_token, "video");
381 if (r == MAILIMF_NO_ERROR)
382 type = MAILMIME_DISCRETE_TYPE_VIDEO;
383 }
384
385 if (r == MAILIMF_ERROR_PARSE) {
386 r = mailimf_token_case_insensitive_parse(message, length,
387 &cur_token, "application");
388 if (r == MAILIMF_NO_ERROR)
389 type = MAILMIME_DISCRETE_TYPE_APPLICATION;
390 }
391
392 if (r == MAILIMF_ERROR_PARSE) {
393 r = mailmime_extension_token_parse(message, length,
394 &cur_token, &extension);
395 if (r == MAILIMF_NO_ERROR)
396 type = MAILMIME_DISCRETE_TYPE_EXTENSION;
397 }
398
399 if (r != MAILIMF_NO_ERROR) {
400 res = r;
401 goto err;
402 }
403
404 discrete_type = mailmime_discrete_type_new(type, extension);
405 if (discrete_type == NULL) {
406 res = MAILIMF_ERROR_MEMORY;
407 goto free;
408 }
409
410 * result = discrete_type;
411 * index = cur_token;
412
413 return MAILIMF_NO_ERROR;
414
415 free:
416 mailmime_extension_token_free(extension);
417 err:
418 return res;
419}
420
421/*
422x encoding := "Content-Transfer-Encoding" ":" mechanism
423*/
424
425int mailmime_encoding_parse(const char * message, size_t length,
426 size_t * index,
427 struct mailmime_mechanism ** result)
428{
429 return mailmime_mechanism_parse(message, length, index, result);
430}
431
432/*
433x entity-headers := [ content CRLF ]
434 [ encoding CRLF ]
435 [ id CRLF ]
436 [ description CRLF ]
437 *( MIME-extension-field CRLF )
438 */
439
440enum {
441 FIELD_STATE_START,
442 FIELD_STATE_T,
443 FIELD_STATE_D
444};
445
446static int guess_field_type(char * name)
447{
448 int state;
449
450 if (* name == 'M')
451 return MAILMIME_FIELD_VERSION;
452
453 if (strncasecmp(name, "Content-", 8) != 0)
454 return MAILMIME_FIELD_NONE;
455
456 name += 8;
457
458 state = FIELD_STATE_START;
459
460 while (1) {
461
462 switch (state) {
463
464 case FIELD_STATE_START:
465 switch ((char) toupper((unsigned char) * name)) {
466 case 'T':
467 state = FIELD_STATE_T;
468 break;
469 case 'I':
470 return MAILMIME_FIELD_ID;
471 case 'D':
472 state = FIELD_STATE_D;
473 break;
474 case 'L':
475 return MAILMIME_FIELD_LANGUAGE;
476 default:
477 return MAILMIME_FIELD_NONE;
478 }
479 break;
480
481 case FIELD_STATE_T:
482 switch ((char) toupper((unsigned char) * name)) {
483 case 'Y':
484 return MAILMIME_FIELD_TYPE;
485 case 'R':
486 return MAILMIME_FIELD_TRANSFER_ENCODING;
487 default:
488 return MAILMIME_FIELD_NONE;
489 }
490 break;
491
492 case FIELD_STATE_D:
493 switch ((char) toupper((unsigned char) * name)) {
494 case 'E':
495 return MAILMIME_FIELD_DESCRIPTION;
496 case 'I':
497 return MAILMIME_FIELD_DISPOSITION;
498 default:
499 return MAILMIME_FIELD_NONE;
500 }
501 break;
502 }
503 name ++;
504 }
505}
506
507int
508mailmime_field_parse(struct mailimf_optional_field * field,
509 struct mailmime_field ** result)
510{
511 char * name;
512 char * value;
513 int guessed_type;
514 size_t cur_token;
515 struct mailmime_content * content;
516 struct mailmime_mechanism * encoding;
517 char * id;
518 char * description;
519 uint32_t version;
520 struct mailmime_field * mime_field;
521 struct mailmime_language * language;
522 struct mailmime_disposition * disposition;
523 int res;
524 int r;
525
526 name = field->fld_name;
527 value = field->fld_value;
528 cur_token = 0;
529
530 content = NULL;
531 encoding = NULL;
532 id = NULL;
533 description = NULL;
534 version = 0;
535 disposition = NULL;
536 language = NULL;
537
538 guessed_type = guess_field_type(name);
539
540 switch (guessed_type) {
541 case MAILMIME_FIELD_TYPE:
542 if (strcasecmp(name, "Content-Type") != 0)
543 return MAILIMF_ERROR_PARSE;
544 r = mailmime_content_parse(value, strlen(value), &cur_token, &content);
545 if (r != MAILIMF_NO_ERROR)
546 return r;
547 break;
548
549 case MAILMIME_FIELD_TRANSFER_ENCODING:
550 if (strcasecmp(name, "Content-Transfer-Encoding") != 0)
551 return MAILIMF_ERROR_PARSE;
552 r = mailmime_encoding_parse(value, strlen(value), &cur_token, &encoding);
553 if (r != MAILIMF_NO_ERROR)
554 return r;
555 break;
556
557 case MAILMIME_FIELD_ID:
558 if (strcasecmp(name, "Content-ID") != 0)
559 return MAILIMF_ERROR_PARSE;
560 r = mailmime_id_parse(value, strlen(value), &cur_token, &id);
561 if (r != MAILIMF_NO_ERROR)
562 return r;
563 break;
564
565 case MAILMIME_FIELD_DESCRIPTION:
566 if (strcasecmp(name, "Content-Description") != 0)
567 return MAILIMF_ERROR_PARSE;
568 r = mailmime_description_parse(value, strlen(value),
569 &cur_token, &description);
570 if (r != MAILIMF_NO_ERROR)
571 return r;
572 break;
573
574 case MAILMIME_FIELD_VERSION:
575 if (strcasecmp(name, "MIME-Version") != 0)
576 return MAILIMF_ERROR_PARSE;
577 r = mailmime_version_parse(value, strlen(value), &cur_token, &version);
578 if (r != MAILIMF_NO_ERROR)
579 return r;
580 break;
581
582 case MAILMIME_FIELD_DISPOSITION:
583 if (strcasecmp(name, "Content-Disposition") != 0)
584 return MAILIMF_ERROR_PARSE;
585 r = mailmime_disposition_parse(value, strlen(value),
586 &cur_token, &disposition);
587 if (r != MAILIMF_NO_ERROR)
588 return r;
589 break;
590
591 case MAILMIME_FIELD_LANGUAGE:
592 if (strcasecmp(name, "Content-Language") != 0)
593 return MAILIMF_ERROR_PARSE;
594 r = mailmime_language_parse(value, strlen(value), &cur_token, &language);
595 if (r != MAILIMF_NO_ERROR)
596 return r;
597 break;
598
599 default:
600 return MAILIMF_ERROR_PARSE;
601 }
602
603 mime_field = mailmime_field_new(guessed_type, content, encoding,
604 id, description, version, disposition,
605 language);
606 if (mime_field == NULL) {
607 res = MAILIMF_ERROR_MEMORY;
608 goto free;
609 }
610
611 * result = mime_field;
612
613 return MAILIMF_NO_ERROR;
614
615 free:
616 if (content != NULL)
617 mailmime_content_free(content);
618 if (encoding != NULL)
619 mailmime_encoding_free(encoding);
620 if (id != NULL)
621 mailmime_id_free(id);
622 if (description != NULL)
623 mailmime_description_free(description);
624 return res;
625}
626
627/*
628x extension-token := ietf-token / x-token
629*/
630
631int
632mailmime_extension_token_parse(const char * message, size_t length,
633 size_t * index, char ** result)
634{
635 return mailmime_token_parse(message, length, index, result);
636}
637
638/*
639 hex-octet := "=" 2(DIGIT / "A" / "B" / "C" / "D" / "E" / "F")
640 ; Octet must be used for characters > 127, =,
641 ; SPACEs or TABs at the ends of lines, and is
642 ; recommended for any character not listed in
643 ; RFC 2049 as "mail-safe".
644*/
645
646/*
647x iana-token := <A publicly-defined extension token. Tokens
648 of this form must be registered with IANA
649 as specified in RFC 2048.>
650*/
651
652/*
653x ietf-token := <An extension token defined by a
654 standards-track RFC and registered
655 with IANA.>
656*/
657
658/*
659x id := "Content-ID" ":" msg-id
660*/
661
662int mailmime_id_parse(const char * message, size_t length,
663 size_t * index, char ** result)
664{
665 return mailimf_msg_id_parse(message, length, index, result);
666}
667
668/*
669x mechanism := "7bit" / "8bit" / "binary" /
670 "quoted-printable" / "base64" /
671 ietf-token / x-token
672*/
673
674static int mailmime_mechanism_parse(const char * message, size_t length,
675 size_t * index,
676 struct mailmime_mechanism ** result)
677{
678 char * token;
679 int type;
680 struct mailmime_mechanism * mechanism;
681 size_t cur_token;
682 int r;
683 int res;
684
685 cur_token = * index;
686
687 type = MAILMIME_MECHANISM_ERROR; /* XXX - removes a gcc warning */
688
689 token = NULL;
690 r = mailimf_token_case_insensitive_parse(message, length,
691 &cur_token, "7bit");
692 if (r == MAILIMF_NO_ERROR)
693 type = MAILMIME_MECHANISM_7BIT;
694
695 if (r == MAILIMF_ERROR_PARSE) {
696 r = mailimf_token_case_insensitive_parse(message, length,
697 &cur_token, "8bit");
698 if (r == MAILIMF_NO_ERROR)
699 type = MAILMIME_MECHANISM_8BIT;
700 }
701
702 if (r == MAILIMF_ERROR_PARSE) {
703 r = mailimf_token_case_insensitive_parse(message, length,
704 &cur_token, "binary");
705 if (r == MAILIMF_NO_ERROR)
706 type = MAILMIME_MECHANISM_BINARY;
707 }
708
709 if (r == MAILIMF_ERROR_PARSE) {
710 r = mailimf_token_case_insensitive_parse(message, length,
711 &cur_token, "quoted-printable");
712 if (r == MAILIMF_NO_ERROR)
713 type = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
714 }
715
716 if (r == MAILIMF_ERROR_PARSE) {
717 r = mailimf_token_case_insensitive_parse(message, length,
718 &cur_token, "base64");
719 if (r == MAILIMF_NO_ERROR)
720 type = MAILMIME_MECHANISM_BASE64;
721 }
722
723 if (r == MAILIMF_ERROR_PARSE) {
724 r = mailmime_token_parse(message, length, &cur_token, &token);
725 if (r == MAILIMF_NO_ERROR)
726 type = MAILMIME_MECHANISM_TOKEN;
727 }
728
729 if (r != MAILIMF_NO_ERROR) {
730 res = r;
731 goto err;
732 }
733
734 mechanism = mailmime_mechanism_new(type, token);
735 if (mechanism == NULL) {
736 res = MAILIMF_ERROR_MEMORY;
737 goto free;
738 }
739
740 * result = mechanism;
741 * index = cur_token;
742
743 return MAILIMF_NO_ERROR;
744
745 free:
746 if (token != NULL)
747 mailmime_token_free(token);
748 err:
749 return res;
750}
751
752/*
753x MIME-extension-field := <Any RFC 822 header field which
754 begins with the string
755 "Content-">
756*/
757
758/*
759in headers
760
761x MIME-message-headers := entity-headers
762 fields
763 version CRLF
764 ; The ordering of the header
765 ; fields implied by this BNF
766 ; definition should be ignored.
767*/
768
769/*
770in message
771
772x MIME-part-headers := entity-headers
773 [fields]
774 ; Any field not beginning with
775 ; "content-" can have no defined
776 ; meaning and may be ignored.
777 ; The ordering of the header
778 ; fields implied by this BNF
779 ; definition should be ignored.
780*/
781
782#if 0
783int
784mailmime_unparsed_fields_parse(struct mailimf_unparsed_fields *
785 fields,
786 struct mailmime_fields **
787 result)
788{
789 clistiter * cur;
790 struct mailmime_fields * mime_fields;
791 clist * list;
792 int r;
793 int res;
794
795 list = clist_new();
796 if (list == NULL) {
797 res = MAILIMF_ERROR_MEMORY;
798 goto err;
799 }
800
801 if (fields->list == NULL) {
802 res = MAILIMF_ERROR_PARSE;
803 goto err;
804 }
805
806 for(cur = clist_begin(fields->list) ; cur != NULL ;
807 cur = clist_next(cur)) {
808 struct mailimf_optional_field * field = cur->data;
809 struct mailmime_field * mime_field;
810
811 r = mailmime_field_parse(field, &mime_field);
812 if (r == MAILIMF_NO_ERROR) {
813 r = clist_append(list, mime_field);
814 if (r < 0) {
815 mailmime_field_free(mime_field);
816 res = MAILIMF_ERROR_MEMORY;
817 goto free_list;
818 }
819 }
820 }
821
822 if (clist_begin(list) == NULL) {
823 res = MAILIMF_ERROR_PARSE;
824 goto free_list;
825 }
826
827 mime_fields = mailmime_fields_new(list);
828 if (mime_fields == NULL) {
829 res = MAILIMF_ERROR_MEMORY;
830 goto free_list;
831 }
832
833 * result = mime_fields;
834
835 return MAILIMF_NO_ERROR;
836
837 free_list:
838 clist_foreach(list, (clist_func) mailmime_field_free, NULL);
839 clist_free(list);
840 err:
841 return res;
842}
843#endif
844
845int
846mailmime_fields_parse(struct mailimf_fields *
847 fields,
848 struct mailmime_fields **
849 result)
850{
851 clistiter * cur;
852 struct mailmime_fields * mime_fields;
853 clist * list;
854 int r;
855 int res;
856
857 list = clist_new();
858 if (list == NULL) {
859 res = MAILIMF_ERROR_MEMORY;
860 goto err;
861 }
862
863 for(cur = clist_begin(fields->fld_list) ; cur != NULL ;
864 cur = clist_next(cur)) {
865 struct mailimf_field * field;
866 struct mailmime_field * mime_field;
867
868 field = clist_content(cur);
869
870 if (field->fld_type == MAILIMF_FIELD_OPTIONAL_FIELD) {
871 r = mailmime_field_parse(field->fld_data.fld_optional_field,
872 &mime_field);
873 if (r == MAILIMF_NO_ERROR) {
874 r = clist_append(list, mime_field);
875 if (r < 0) {
876 mailmime_field_free(mime_field);
877 res = MAILIMF_ERROR_MEMORY;
878 goto free_list;
879 }
880 }
881 else if (r == MAILIMF_ERROR_PARSE) {
882 /* do nothing */
883 }
884 else {
885 res = r;
886 goto free_list;
887 }
888 }
889 }
890
891 if (clist_begin(list) == NULL) {
892 res = MAILIMF_ERROR_PARSE;
893 goto free_list;
894 }
895
896 mime_fields = mailmime_fields_new(list);
897 if (mime_fields == NULL) {
898 res = MAILIMF_ERROR_MEMORY;
899 goto free_list;
900 }
901
902 * result = mime_fields;
903
904 return MAILIMF_NO_ERROR;
905
906 free_list:
907 clist_foreach(list, (clist_func) mailmime_field_free, NULL);
908 clist_free(list);
909 err:
910 return res;
911}
912
913/*
914x parameter := attribute "=" value
915*/
916
917int mailmime_parameter_parse(const char * message, size_t length,
918 size_t * index,
919 struct mailmime_parameter ** result)
920{
921 char * attribute;
922 char * value;
923 struct mailmime_parameter * parameter;
924 size_t cur_token;
925 int r;
926 int res;
927
928 cur_token = * index;
929
930 r = mailmime_attribute_parse(message, length, &cur_token, &attribute);
931 if (r != MAILIMF_NO_ERROR) {
932 res = r;
933 goto err;
934 }
935
936 r = mailimf_unstrict_char_parse(message, length, &cur_token, '=');
937 if (r != MAILIMF_NO_ERROR) {
938 res = r;
939 goto free_attr;
940 }
941
942 r = mailimf_cfws_parse(message, length, &cur_token);
943 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
944 res = r;
945 goto free_attr;
946 }
947
948 r = mailmime_value_parse(message, length, &cur_token, &value);
949 if (r != MAILIMF_NO_ERROR) {
950 res = r;
951 goto free_attr;
952 }
953
954 parameter = mailmime_parameter_new(attribute, value);
955 if (parameter == NULL) {
956 res = MAILIMF_ERROR_MEMORY;
957 goto free_value;
958 }
959
960 * result = parameter;
961 * index = cur_token;
962
963 return MAILIMF_NO_ERROR;
964
965 free_value:
966 mailmime_value_free(value);
967 free_attr:
968 mailmime_attribute_free(attribute);
969 err:
970 return res;
971}
972
973/*
974 ptext := hex-octet / safe-char
975*/
976
977/*
978 qp-line := *(qp-segment transport-padding CRLF)
979 qp-part transport-padding
980*/
981
982/*
983 qp-part := qp-section
984 ; Maximum length of 76 characters
985*/
986
987/*
988 qp-section := [*(ptext / SPACE / TAB) ptext]
989*/
990
991/*
992 qp-segment := qp-section *(SPACE / TAB) "="
993 ; Maximum length of 76 characters
994*/
995
996/*
997 quoted-printable := qp-line *(CRLF qp-line)
998*/
999
1000/*
1001 safe-char := <any octet with decimal value of 33 through
1002 60 inclusive, and 62 through 126>
1003 ; Characters not listed as "mail-safe" in
1004 ; RFC 2049 are also not recommended.
1005*/
1006
1007/*
1008x subtype := extension-token / iana-token
1009*/
1010
1011static int mailmime_subtype_parse(const char * message, size_t length,
1012 size_t * index, char ** result)
1013{
1014 return mailmime_extension_token_parse(message, length, index, result);
1015}
1016
1017/*
1018x token := 1*<any (US-ASCII) CHAR except SPACE, CTLs,
1019 or tspecials>
1020*/
1021
1022static int is_token(char ch)
1023{
1024 unsigned char uch = (unsigned char) ch;
1025
1026 if (uch > 0x7F)
1027 return FALSE;
1028
1029 if (uch == ' ')
1030 return FALSE;
1031
1032 if (is_tspecials(ch))
1033 return FALSE;
1034
1035 return TRUE;
1036}
1037
1038
1039static int mailmime_token_parse(const char * message, size_t length,
1040 size_t * index,
1041 char ** token)
1042{
1043 return mailimf_custom_string_parse(message, length,
1044 index, token,
1045 is_token);
1046}
1047
1048/*
1049 transport-padding := *LWSP-char
1050 ; Composers MUST NOT generate
1051 ; non-zero length transport
1052 ; padding, but receivers MUST
1053 ; be able to handle padding
1054 ; added by message transports.
1055*/
1056
1057/*
1058enum {
1059 LWSP_1,
1060 LWSP_2,
1061 LWSP_3,
1062 LWSP_4,
1063 LWSP_OK
1064};
1065
1066gboolean mailmime_transport_padding_parse(gconst char * message, guint32 length,
1067 guint32 * index)
1068{
1069 guint32 cur_token;
1070 gint state;
1071 guint32 last_valid_pos;
1072
1073 cur_token = * index;
1074
1075 if (cur_token >= length)
1076 return FALSE;
1077
1078 state = LWSP_1;
1079
1080 while (state != LWSP_OUT) {
1081
1082 if (cur_token >= length)
1083 return FALSE;
1084
1085 switch (state) {
1086 case LWSP_1:
1087 last_valid_pos = cur_token;
1088
1089 switch (message[cur_token]) {
1090 case '\r':
1091 state = LWSP_2;
1092 break;
1093 case '\n':
1094 state = LWSP_3;
1095 break;
1096 case ' ':
1097 case '\t':
1098 state = LWSP_4;
1099 break;
1100 default:
1101 state = LWSP_OK;
1102 break;
1103 }
1104 case LWSP_2:
1105 switch (message[cur_token]) {
1106 case '\n':
1107 state = LWSP_3;
1108 break;
1109 default:
1110 state = LWSP_OUT;
1111 cur_token = last_valid_pos;
1112 break;
1113 }
1114 case LWSP_3:
1115 switch (message[cur_token]) {
1116 case ' ':
1117 case '\t':
1118 state = LWSP_1;
1119 break;
1120 default:
1121 state = LWSP_OUT;
1122 cur_token = last_valid_pos;
1123 break;
1124 }
1125
1126 cur_token ++;
1127 }
1128 }
1129
1130 * index = cur_token;
1131
1132 return TRUE;
1133}
1134*/
1135
1136/*
1137x tspecials := "(" / ")" / "<" / ">" / "@" /
1138 "," / ";" / ":" / "\" / <">
1139 "/" / "[" / "]" / "?" / "="
1140 ; Must be in quoted-string,
1141 ; to use within parameter values
1142*/
1143
1144static int is_tspecials(char ch)
1145{
1146 switch (ch) {
1147 case '(':
1148 case ')':
1149 case '<':
1150 case '>':
1151 case '@':
1152 case ',':
1153 case ';':
1154 case ':':
1155 case '\\':
1156 case '\"':
1157 case '/':
1158 case '[':
1159 case ']':
1160 case '?':
1161 case '=':
1162 return TRUE;
1163 default:
1164 return FALSE;
1165 }
1166}
1167
1168/*
1169x type := discrete-type / composite-type
1170*/
1171
1172static int mailmime_type_parse(const char * message, size_t length,
1173 size_t * index,
1174 struct mailmime_type ** result)
1175{
1176 struct mailmime_discrete_type * discrete_type;
1177 struct mailmime_composite_type * composite_type;
1178 size_t cur_token;
1179 struct mailmime_type * mime_type;
1180 int type;
1181 int res;
1182 int r;
1183
1184 cur_token = * index;
1185
1186 discrete_type = NULL;
1187 composite_type = NULL;
1188
1189 type = MAILMIME_TYPE_ERROR; /* XXX - removes a gcc warning */
1190
1191 r = mailmime_composite_type_parse(message, length, &cur_token,
1192 &composite_type);
1193 if (r == MAILIMF_NO_ERROR)
1194 type = MAILMIME_TYPE_COMPOSITE_TYPE;
1195
1196 if (r == MAILIMF_ERROR_PARSE) {
1197 r = mailmime_discrete_type_parse(message, length, &cur_token,
1198 &discrete_type);
1199 if (r == MAILIMF_NO_ERROR)
1200 type = MAILMIME_TYPE_DISCRETE_TYPE;
1201 }
1202
1203 if (r != MAILIMF_NO_ERROR) {
1204 res = r;
1205 goto err;
1206 }
1207
1208 mime_type = mailmime_type_new(type, discrete_type, composite_type);
1209 if (mime_type == NULL) {
1210 res = r;
1211 goto free;
1212 }
1213
1214 * result = mime_type;
1215 * index = cur_token;
1216
1217 return MAILIMF_NO_ERROR;
1218
1219 free:
1220 if (discrete_type != NULL)
1221 mailmime_discrete_type_free(discrete_type);
1222 if (composite_type != NULL)
1223 mailmime_composite_type_free(composite_type);
1224 err:
1225 return res;
1226}
1227
1228/*
1229x value := token / quoted-string
1230*/
1231
1232int mailmime_value_parse(const char * message, size_t length,
1233 size_t * index, char ** result)
1234{
1235 int r;
1236
1237 r = mailmime_token_parse(message, length, index, result);
1238
1239 if (r == MAILIMF_ERROR_PARSE)
1240 r = mailimf_quoted_string_parse(message, length, index, result);
1241
1242 if (r != MAILIMF_NO_ERROR)
1243 return r;
1244
1245 return MAILIMF_NO_ERROR;
1246}
1247
1248/*
1249x version := "MIME-Version" ":" 1*DIGIT "." 1*DIGIT
1250*/
1251
1252int mailmime_version_parse(const char * message, size_t length,
1253 size_t * index,
1254 uint32_t * result)
1255{
1256 size_t cur_token;
1257 uint32_t hi;
1258 uint32_t low;
1259 uint32_t version;
1260 int r;
1261
1262 cur_token = * index;
1263
1264 r = mailimf_number_parse(message, length, &cur_token, &hi);
1265 if (r != MAILIMF_NO_ERROR)
1266 return r;
1267
1268 r = mailimf_unstrict_char_parse(message, length, &cur_token, '.');
1269 if (r != MAILIMF_NO_ERROR)
1270 return r;
1271
1272 r = mailimf_cfws_parse(message, length, &cur_token);
1273 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
1274 return r;
1275
1276 r = mailimf_number_parse(message, length, &cur_token, &low);
1277 if (r != MAILIMF_NO_ERROR)
1278 return r;
1279
1280 version = (hi << 16) + low;
1281
1282 * result = version;
1283 * index = cur_token;
1284
1285 return MAILIMF_NO_ERROR;
1286}
1287
1288/*
1289x x-token := <The two characters "X-" or "x-" followed, with
1290 no intervening white space, by any token>
1291*/
1292
1293/*
1294static gboolean mailmime_x_token_parse(gconst char * message, guint32 length,
1295 guint32 * index,
1296 gchar ** result)
1297{
1298 guint32 cur_token;
1299 gchar * token;
1300 gchar * x_token;
1301 gboolean min_x;
1302
1303 cur_token = * index;
1304
1305 if (!mailimf_char_parse(message, length, &cur_token, 'x')) {
1306 if (!mailimf_char_parse(message, length, &cur_token, 'X'))
1307 return FALSE;
1308 min_x = FALSE;
1309 }
1310 else
1311 min_x = TRUE;
1312
1313 if (!mailimf_char_parse(message, length, &cur_token, '-'))
1314 return FALSE;
1315
1316 if (!mailmime_token_parse(message, length, &cur_token, &token))
1317 return FALSE;
1318
1319 if (min_x)
1320 x_token = g_strconcat("x-", token, NULL);
1321 else
1322 x_token = g_strconcat("X-", token, NULL);
1323 mailmime_token_free(token);
1324
1325 if (x_token == NULL)
1326 return FALSE;
1327
1328 * result = x_token;
1329 * index = cur_token;
1330
1331 return TRUE;
1332}
1333*/
1334
1335
1336int mailmime_language_parse(const char * message, size_t length,
1337 size_t * index,
1338 struct mailmime_language ** result)
1339{
1340 size_t cur_token;
1341 int r;
1342 int res;
1343 clist * list;
1344 int first;
1345 struct mailmime_language * language;
1346
1347 cur_token = * index;
1348
1349 list = clist_new();
1350 if (list == NULL) {
1351 res = MAILIMF_ERROR_MEMORY;
1352 goto err;
1353 }
1354
1355 first = TRUE;
1356
1357 while (1) {
1358 char * atom;
1359
1360 r = mailimf_unstrict_char_parse(message, length, &cur_token, ',');
1361 if (r == MAILIMF_NO_ERROR) {
1362 /* do nothing */
1363 }
1364 else if (r == MAILIMF_ERROR_PARSE) {
1365 break;
1366 }
1367 else {
1368 res = r;
1369 goto err;
1370 }
1371
1372 r = mailimf_atom_parse(message, length, &cur_token, &atom);
1373 if (r == MAILIMF_NO_ERROR) {
1374 /* do nothing */
1375 }
1376 else if (r == MAILIMF_ERROR_PARSE) {
1377 break;
1378 }
1379 else {
1380 res = r;
1381 goto err;
1382 }
1383
1384 r = clist_append(list, atom);
1385 if (r < 0) {
1386 mailimf_atom_free(atom);
1387 res = MAILIMF_ERROR_MEMORY;
1388 goto free;
1389 }
1390 }
1391
1392 language = mailmime_language_new(list);
1393 if (language == NULL) {
1394 res = MAILIMF_ERROR_MEMORY;
1395 goto free;
1396 }
1397
1398 * result = language;
1399 * index = cur_token;
1400
1401 return MAILIMF_NO_ERROR;
1402
1403 free:
1404 clist_foreach(list, (clist_func) mailimf_atom_free, NULL);
1405 clist_free(list);
1406 err:
1407 return res;
1408}
diff --git a/kmicromail/libetpan/mime/mailmime.h b/kmicromail/libetpan/mime/mailmime.h
new file mode 100644
index 0000000..c834967
--- a/dev/null
+++ b/kmicromail/libetpan/mime/mailmime.h
@@ -0,0 +1,100 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMIME_H
37
38#define MAILMIME_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailimf.h>
45#include <libetpan/mailmime_types.h>
46#include <libetpan/mailmime_types_helper.h>
47#include <libetpan/mailmime_content.h>
48#include <libetpan/mailmime_decode.h>
49#include <libetpan/mailmime_disposition.h>
50#include <libetpan/mailmime_write.h>
51
52int mailmime_content_parse(const char * message, size_t length,
53 size_t * index,
54 struct mailmime_content ** result);
55
56int mailmime_description_parse(const char * message, size_t length,
57 size_t * index,
58 char ** result);
59
60int mailmime_encoding_parse(const char * message, size_t length,
61 size_t * index,
62 struct mailmime_mechanism ** result);
63
64int
65mailmime_field_parse(struct mailimf_optional_field * field,
66 struct mailmime_field ** result);
67
68int mailmime_id_parse(const char * message, size_t length,
69 size_t * index, char ** result);
70
71int
72mailmime_fields_parse(struct mailimf_fields *
73 fields,
74 struct mailmime_fields **
75 result);
76
77int mailmime_version_parse(const char * message, size_t length,
78 size_t * index,
79 uint32_t * result);
80
81int
82mailmime_extension_token_parse(const char * message, size_t length,
83 size_t * index, char ** result);
84
85int mailmime_parameter_parse(const char * message, size_t length,
86 size_t * index,
87 struct mailmime_parameter ** result);
88
89int mailmime_value_parse(const char * message, size_t length,
90 size_t * index, char ** result);
91
92int mailmime_language_parse(const char * message, size_t length,
93 size_t * index,
94 struct mailmime_language ** result);
95
96#ifdef __cplusplus
97}
98#endif
99
100#endif
diff --git a/kmicromail/libetpan/mime/mailmime_content.c b/kmicromail/libetpan/mime/mailmime_content.c
new file mode 100644
index 0000000..c73812d
--- a/dev/null
+++ b/kmicromail/libetpan/mime/mailmime_content.c
@@ -0,0 +1,2164 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailimf.h"
37
38#include <string.h>
39#include <stdlib.h>
40
41#include "mailmime.h"
42#include "mailmime_types.h"
43#include "mmapstring.h"
44
45#ifndef TRUE
46#define TRUE 1
47#endif
48
49#ifndef FALSE
50#define FALSE 0
51#endif
52
53/*
54 RFC 2045
55 RFC 2046
56 RFC 2047
57
58 RFC 2231
59*/
60
61
62static int mailmime_parse_with_default(const char * message, size_t length,
63 size_t * index, int default_type,
64 struct mailmime_content * content_type,
65 struct mailmime_fields * mime_fields,
66 struct mailmime ** result);
67
68
69
70char * mailmime_content_charset_get(struct mailmime_content * content)
71{
72 char * charset;
73
74 charset = mailmime_content_param_get(content, "charset");
75 if (charset == NULL)
76 return "us-ascii";
77 else
78 return charset;
79}
80
81char * mailmime_content_param_get(struct mailmime_content * content,
82 char * name)
83{
84 clistiter * cur;
85
86 for(cur = clist_begin(content->ct_parameters) ;
87 cur != NULL ; cur = clist_next(cur)) {
88 struct mailmime_parameter * param;
89
90 param = clist_content(cur);
91
92 if (strcasecmp(param->pa_name, name) == 0)
93 return param->pa_value;
94 }
95
96 return NULL;
97}
98
99
100/*
101 boundary := 0*69<bchars> bcharsnospace
102*/
103
104/*
105 bchars := bcharsnospace / " "
106*/
107
108/*
109 bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" /
110 "+" / "_" / "," / "-" / "." /
111 "/" / ":" / "=" / "?"
112*/
113
114/*
115 body-part := <"message" as defined in RFC 822, with all
116 header fields optional, not starting with the
117 specified dash-boundary, and with the
118 delimiter not occurring anywhere in the
119 body part. Note that the semantics of a
120 part differ from the semantics of a message,
121 as described in the text.>
122*/
123
124/*
125 close-delimiter := delimiter "--"
126*/
127
128/*
129 dash-boundary := "--" boundary
130 ; boundary taken from the value of
131 ; boundary parameter of the
132 ; Content-Type field.
133*/
134
135/*
136 delimiter := CRLF dash-boundary
137*/
138
139/*
140 discard-text := *(*text CRLF)
141 ; May be ignored or discarded.
142*/
143
144/*
145 encapsulation := delimiter transport-padding
146 CRLF body-part
147*/
148
149/*
150 epilogue := discard-text
151*/
152
153/*
154 multipart-body := [preamble CRLF]
155 dash-boundary transport-padding CRLF
156 body-part *encapsulation
157 close-delimiter transport-padding
158 [CRLF epilogue]
159*/
160
161/*
162 preamble := discard-text
163*/
164
165/*
166 transport-padding := *LWSP-char
167 ; Composers MUST NOT generate
168 ; non-zero length transport
169 ; padding, but receivers MUST
170 ; be able to handle padding
171 ; added by message transports.
172*/
173
174
175/*
176 ACCESS-TYPE
177 EXPIRATION
178 SIZE
179 PERMISSION
180*/
181
182/*
183 5.2.3.2. The 'ftp' and 'tftp' Access-Types
184 NAME
185 SITE
186
187 (3) Before any data are retrieved, using FTP, the user will
188 generally need to be asked to provide a login id and a
189 password for the machine named by the site parameter.
190 For security reasons, such an id and password are not
191 specified as content-type parameters, but must be
192 obtained from the user.
193
194 optional :
195 DIRECTORY
196 MODE
197*/
198
199/*
2005.2.3.3. The 'anon-ftp' Access-Type
201*/
202
203/*
2045.2.3.4. The 'local-file' Access-Type
205NAME
206SITE
207*/
208
209/*
2105.2.3.5. The 'mail-server' Access-Type
211SERVER
212SUBJECT
213*/
214
215
216enum {
217 PREAMBLE_STATE_A0,
218 PREAMBLE_STATE_A,
219 PREAMBLE_STATE_A1,
220 PREAMBLE_STATE_B,
221 PREAMBLE_STATE_C,
222 PREAMBLE_STATE_D,
223 PREAMBLE_STATE_E
224};
225
226static int mailmime_preamble_parse(const char * message, size_t length,
227 size_t * index, int beol)
228{
229 int state;
230 size_t cur_token;
231
232 cur_token = * index;
233 if (beol)
234 state = PREAMBLE_STATE_A0;
235 else
236 state = PREAMBLE_STATE_A;
237
238 while (state != PREAMBLE_STATE_E) {
239
240 if (cur_token >= length)
241 return MAILIMF_ERROR_PARSE;
242
243 switch (state) {
244 case PREAMBLE_STATE_A0:
245 switch (message[cur_token]) {
246 case '-':
247 state = PREAMBLE_STATE_A1;
248 break;
249 case '\r':
250 state = PREAMBLE_STATE_B;
251 break;
252 case '\n':
253 state = PREAMBLE_STATE_C;
254 break;
255 default:
256 state = PREAMBLE_STATE_A;
257 break;
258 }
259 break;
260
261 case PREAMBLE_STATE_A:
262 switch (message[cur_token]) {
263 case '\r':
264 state = PREAMBLE_STATE_B;
265 break;
266 case '\n':
267 state = PREAMBLE_STATE_C;
268 break;
269 default:
270 state = PREAMBLE_STATE_A;
271 break;
272 }
273 break;
274
275 case PREAMBLE_STATE_A1:
276 switch (message[cur_token]) {
277 case '-':
278 state = PREAMBLE_STATE_E;
279 break;
280 case '\r':
281 state = PREAMBLE_STATE_B;
282 break;
283 case '\n':
284 state = PREAMBLE_STATE_C;
285 break;
286 default:
287 state = PREAMBLE_STATE_A;
288 break;
289 }
290 break;
291
292 case PREAMBLE_STATE_B:
293 switch (message[cur_token]) {
294 case '\r':
295 state = PREAMBLE_STATE_B;
296 break;
297 case '\n':
298 state = PREAMBLE_STATE_C;
299 break;
300 case '-':
301 state = PREAMBLE_STATE_D;
302 break;
303 default:
304 state = PREAMBLE_STATE_A0;
305 break;
306 }
307 break;
308
309 case PREAMBLE_STATE_C:
310 switch (message[cur_token]) {
311 case '-':
312 state = PREAMBLE_STATE_D;
313 break;
314 case '\r':
315 state = PREAMBLE_STATE_B;
316 break;
317 case '\n':
318 state = PREAMBLE_STATE_C;
319 break;
320 default:
321 state = PREAMBLE_STATE_A0;
322 break;
323 }
324 break;
325
326 case PREAMBLE_STATE_D:
327 switch (message[cur_token]) {
328 case '-':
329 state = PREAMBLE_STATE_E;
330 break;
331 default:
332 state = PREAMBLE_STATE_A;
333 break;
334 }
335 break;
336 }
337
338 cur_token ++;
339 }
340
341 * index = cur_token;
342
343 return MAILIMF_NO_ERROR;
344}
345
346static int mailmime_boundary_parse(const char * message, size_t length,
347 size_t * index, char * boundary)
348{
349 size_t cur_token;
350 size_t len;
351
352 cur_token = * index;
353
354 len = strlen(boundary);
355
356 if (cur_token + len >= length)
357 return MAILIMF_ERROR_PARSE;
358
359 if (strncmp(message + cur_token, boundary, len) != 0)
360 return MAILIMF_ERROR_PARSE;
361
362 cur_token += len;
363
364 * index = cur_token;
365
366 return MAILIMF_NO_ERROR;
367}
368
369static int is_wsp(char ch)
370{
371 if ((ch == ' ') || (ch == '\t'))
372 return TRUE;
373
374 return FALSE;
375}
376
377static int mailmime_lwsp_parse(const char * message, size_t length,
378 size_t * index)
379{
380 size_t cur_token;
381
382 cur_token = * index;
383
384 if (cur_token >= length)
385 return MAILIMF_ERROR_PARSE;
386
387 while (is_wsp(message[cur_token])) {
388 cur_token ++;
389 if (cur_token >= length)
390 break;
391 }
392
393 if (cur_token == * index)
394 return MAILIMF_ERROR_PARSE;
395
396 * index = cur_token;
397
398 return MAILIMF_NO_ERROR;
399}
400
401/*
402gboolean mailimf_crlf_parse(gchar * message, guint32 length, guint32 * index)
403*/
404
405enum {
406 BODY_PART_DASH2_STATE_0,
407 BODY_PART_DASH2_STATE_1,
408 BODY_PART_DASH2_STATE_2,
409 BODY_PART_DASH2_STATE_3,
410 BODY_PART_DASH2_STATE_4,
411 BODY_PART_DASH2_STATE_5,
412 BODY_PART_DASH2_STATE_6
413};
414
415static int
416mailmime_body_part_dash2_parse(const char * message, size_t length,
417 size_t * index, char * boundary,
418 const char ** result, size_t * result_size)
419{
420 int state;
421 size_t cur_token;
422 size_t size;
423 size_t begin_text;
424 size_t end_text;
425 int r;
426
427 cur_token = * index;
428 state = BODY_PART_DASH2_STATE_0;
429
430 begin_text = cur_token;
431 end_text = length;
432
433 while (state != BODY_PART_DASH2_STATE_5) {
434
435 if (cur_token >= length)
436 break;
437
438 switch(state) {
439
440 case BODY_PART_DASH2_STATE_0:
441 switch (message[cur_token]) {
442 case '\r':
443 state = BODY_PART_DASH2_STATE_1;
444 break;
445 case '\n':
446 state = BODY_PART_DASH2_STATE_2;
447 break;
448 default:
449 state = BODY_PART_DASH2_STATE_0;
450 break;
451 }
452 break;
453
454 case BODY_PART_DASH2_STATE_1:
455 switch (message[cur_token]) {
456 case '\n':
457 state = BODY_PART_DASH2_STATE_2;
458 break;
459 default:
460 state = BODY_PART_DASH2_STATE_0;
461 break;
462 }
463 break;
464
465 case BODY_PART_DASH2_STATE_2:
466 switch (message[cur_token]) {
467 case '-':
468 end_text = cur_token;
469 state = BODY_PART_DASH2_STATE_3;
470 break;
471 case '\r':
472 state = BODY_PART_DASH2_STATE_1;
473 break;
474 case '\n':
475 state = BODY_PART_DASH2_STATE_2;
476 break;
477 default:
478 state = BODY_PART_DASH2_STATE_0;
479 break;
480 }
481 break;
482
483 case BODY_PART_DASH2_STATE_3:
484 switch (message[cur_token]) {
485 case '\r':
486 state = BODY_PART_DASH2_STATE_1;
487 break;
488 case '\n':
489 state = BODY_PART_DASH2_STATE_2;
490 break;
491 case '-':
492 state = BODY_PART_DASH2_STATE_4;
493 break;
494 default:
495 state = BODY_PART_DASH2_STATE_0;
496 break;
497 }
498 break;
499
500 case BODY_PART_DASH2_STATE_4:
501 r = mailmime_boundary_parse(message, length, &cur_token, boundary);
502 if (r == MAILIMF_NO_ERROR)
503 state = BODY_PART_DASH2_STATE_5;
504 else
505 state = BODY_PART_DASH2_STATE_6;
506
507 break;
508 }
509
510 if ((state != BODY_PART_DASH2_STATE_5) &&
511 (state != BODY_PART_DASH2_STATE_6))
512 cur_token ++;
513
514 if (state == BODY_PART_DASH2_STATE_6)
515 state = BODY_PART_DASH2_STATE_0;
516 }
517
518 end_text --;
519 if (end_text >= 1)
520 if (message[end_text - 1] == '\r')
521 end_text --;
522
523 size = end_text - begin_text;
524
525#if 0
526 body_part = mailimf_body_new(message + begin_text, size);
527 if (body_part == NULL)
528 goto err;
529#endif
530
531 * result = message + begin_text;
532 * result_size = size;
533 * index = cur_token;
534
535 return MAILIMF_NO_ERROR;
536#if 0
537 err:
538 return MAILIMF_ERROR_PARSE;
539#endif
540}
541
542enum {
543 MULTIPART_CLOSE_STATE_0,
544 MULTIPART_CLOSE_STATE_1,
545 MULTIPART_CLOSE_STATE_2,
546 MULTIPART_CLOSE_STATE_3,
547 MULTIPART_CLOSE_STATE_4
548};
549
550static int mailmime_multipart_close_parse(const char * message, size_t length,
551 size_t * index)
552{
553 int state;
554 size_t cur_token;
555
556 cur_token = * index;
557 state = MULTIPART_CLOSE_STATE_0;
558
559 while (state != MULTIPART_CLOSE_STATE_4) {
560
561 switch(state) {
562
563 case MULTIPART_CLOSE_STATE_0:
564 if (cur_token >= length)
565 return MAILIMF_ERROR_PARSE;
566
567 switch (message[cur_token]) {
568 case '-':
569 state = MULTIPART_CLOSE_STATE_1;
570 break;
571 default:
572 return MAILIMF_ERROR_PARSE;
573 }
574 break;
575
576 case MULTIPART_CLOSE_STATE_1:
577 if (cur_token >= length)
578 return MAILIMF_ERROR_PARSE;
579
580 switch (message[cur_token]) {
581 case '-':
582 state = MULTIPART_CLOSE_STATE_2;
583 break;
584 default:
585 return MAILIMF_ERROR_PARSE;
586 }
587 break;
588
589 case MULTIPART_CLOSE_STATE_2:
590 if (cur_token >= length) {
591 state = MULTIPART_CLOSE_STATE_4;
592 break;
593 }
594
595 switch (message[cur_token]) {
596 case ' ':
597 state = MULTIPART_CLOSE_STATE_2;
598 break;
599 case '\t':
600 state = MULTIPART_CLOSE_STATE_2;
601 break;
602 case '\r':
603 state = MULTIPART_CLOSE_STATE_3;
604 break;
605 case '\n':
606 state = MULTIPART_CLOSE_STATE_4;
607 break;
608 default:
609 state = MULTIPART_CLOSE_STATE_4;
610 break;
611 }
612 break;
613
614 case MULTIPART_CLOSE_STATE_3:
615 if (cur_token >= length) {
616 state = MULTIPART_CLOSE_STATE_4;
617 break;
618 }
619
620 switch (message[cur_token]) {
621 case '\n':
622 state = MULTIPART_CLOSE_STATE_4;
623 break;
624 default:
625 state = MULTIPART_CLOSE_STATE_4;
626 break;
627 }
628 break;
629 }
630
631 cur_token ++;
632 }
633
634 * index = cur_token;
635
636 return MAILIMF_NO_ERROR;
637}
638
639enum {
640 MULTIPART_NEXT_STATE_0,
641 MULTIPART_NEXT_STATE_1,
642 MULTIPART_NEXT_STATE_2
643};
644
645int mailmime_multipart_next_parse(const char * message, size_t length,
646 size_t * index)
647{
648 int state;
649 size_t cur_token;
650
651 cur_token = * index;
652 state = MULTIPART_NEXT_STATE_0;
653
654 while (state != MULTIPART_NEXT_STATE_2) {
655
656 if (cur_token >= length)
657 return MAILIMF_ERROR_PARSE;
658
659 switch(state) {
660
661 case MULTIPART_NEXT_STATE_0:
662 switch (message[cur_token]) {
663 case ' ':
664 state = MULTIPART_NEXT_STATE_0;
665 break;
666 case '\t':
667 state = MULTIPART_NEXT_STATE_0;
668 break;
669 case '\r':
670 state = MULTIPART_NEXT_STATE_1;
671 break;
672 case '\n':
673 state = MULTIPART_NEXT_STATE_2;
674 break;
675 default:
676 return MAILIMF_ERROR_PARSE;
677 }
678 break;
679
680 case MULTIPART_NEXT_STATE_1:
681 switch (message[cur_token]) {
682 case '\n':
683 state = MULTIPART_NEXT_STATE_2;
684 break;
685 default:
686 return MAILIMF_ERROR_PARSE;
687 }
688 break;
689 }
690
691 cur_token ++;
692 }
693
694 * index = cur_token;
695
696 return MAILIMF_NO_ERROR;
697}
698
699static int
700mailmime_multipart_body_parse(const char * message, size_t length,
701 size_t * index, char * boundary,
702 int default_subtype,
703 clist ** result,
704 struct mailmime_data ** p_preamble,
705 struct mailmime_data ** p_epilogue)
706{
707 size_t cur_token;
708 clist * list;
709 int r;
710 int res;
711#if 0
712 size_t begin;
713#endif
714 size_t preamble_begin;
715 size_t preamble_length;
716 size_t preamble_end;
717#if 0
718 int no_preamble;
719 size_t before_crlf;
720#endif
721 size_t epilogue_begin;
722 size_t epilogue_length;
723 struct mailmime_data * preamble;
724 struct mailmime_data * epilogue;
725 size_t part_begin;
726
727 preamble = NULL;
728 epilogue = NULL;
729
730 cur_token = * index;
731 preamble_begin = cur_token;
732
733#if 0
734 no_preamble = FALSE;
735#endif
736 preamble_end = preamble_begin;
737
738#if 0
739 r = mailmime_preamble_parse(message, length, &cur_token);
740 if (r == MAILIMF_NO_ERROR) {
741 /* do nothing */
742#if 0
743 preamble_end = cur_token - 2;
744#endif
745 }
746 else if (r == MAILIMF_ERROR_PARSE) {
747 /* do nothing */
748 no_preamble = TRUE;
749 }
750 else {
751 res = r;
752 goto err;
753 }
754
755 while (1) {
756
757 preamble_end = cur_token;
758 r = mailmime_boundary_parse(message, length, &cur_token, boundary);
759 if (r == MAILIMF_NO_ERROR) {
760 break;
761 }
762 else if (r == MAILIMF_ERROR_PARSE) {
763 /* do nothing */
764 }
765 else {
766 res = r;
767 goto err;
768 }
769
770 r = mailmime_preamble_parse(message, length, &cur_token);
771 if (r == MAILIMF_NO_ERROR) {
772#if 0
773 preamble_end = cur_token - 2;
774#endif
775 }
776 else if (r == MAILIMF_ERROR_PARSE) {
777 no_preamble = TRUE;
778 break;
779 }
780 else {
781 res = r;
782 goto err;
783 }
784 }
785
786 if (no_preamble) {
787#if 0
788 preamble_end = cur_token;
789#endif
790 }
791 else {
792
793 r = mailmime_lwsp_parse(message, length, &cur_token);
794 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
795 res = r;
796 goto err;
797 }
798
799 before_crlf = cur_token;
800 r = mailimf_crlf_parse(message, length, &cur_token);
801 if (r == MAILIMF_NO_ERROR) {
802#if 0
803 preamble_end = before_crlf;
804#endif
805 /* remove the CR LF at the end of preamble if any */
806 }
807 else if (r == MAILIMF_ERROR_PARSE) {
808 /* do nothing */
809 }
810 else {
811 res = r;
812 goto err;
813 }
814 }
815 preamble_length = preamble_end - begin;
816#endif
817
818 r = mailmime_preamble_parse(message, length, &cur_token, 1);
819 if (r == MAILIMF_NO_ERROR) {
820 while (1) {
821
822 preamble_end = cur_token;
823 r = mailmime_boundary_parse(message, length, &cur_token, boundary);
824 if (r == MAILIMF_NO_ERROR) {
825 break;
826 }
827 else if (r == MAILIMF_ERROR_PARSE) {
828 /* do nothing */
829 }
830 else {
831 res = r;
832 goto err;
833 }
834
835 r = mailmime_preamble_parse(message, length, &cur_token, 0);
836 if (r == MAILIMF_NO_ERROR) {
837 }
838 else if (r == MAILIMF_ERROR_PARSE) {
839 break;
840 }
841 else {
842 res = r;
843 goto err;
844 }
845 }
846 }
847
848 preamble_end -= 2;
849 if (preamble_end != preamble_begin) {
850 /* try to find the real end of the preamble (strip CR LF) */
851 if (message[preamble_end - 1] == '\n') {
852 preamble_end --;
853 if (preamble_end - 1 >= preamble_begin) {
854 if (message[preamble_end - 1] == '\r')
855 preamble_end --;
856 }
857 }
858 else if (message[preamble_end - 1] == '\r') {
859 preamble_end --;
860 }
861 }
862 preamble_length = preamble_end - preamble_begin;
863
864 part_begin = cur_token;
865 while (1) {
866 r = mailmime_lwsp_parse(message, length, &cur_token);
867 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
868 res = r;
869 goto err;
870 }
871#if 0
872 if (r == MAILIMF_ERROR_PARSE)
873 break;
874#endif
875
876 r = mailimf_crlf_parse(message, length, &cur_token);
877 if (r == MAILIMF_NO_ERROR) {
878 part_begin = cur_token;
879 }
880 else if (r == MAILIMF_ERROR_PARSE) {
881 /* do nothing */
882 break;
883 }
884 else {
885 res = r;
886 goto err;
887 }
888 }
889
890 cur_token = part_begin;
891
892 list = clist_new();
893 if (list == NULL) {
894 res = MAILIMF_ERROR_MEMORY;
895 goto err;
896 }
897
898 while (1) {
899 size_t bp_token;
900 struct mailmime * mime_bp;
901 const char * data_str;
902 size_t data_size;
903 struct mailimf_fields * fields;
904 struct mailmime_fields * mime_fields;
905
906 r = mailmime_body_part_dash2_parse(message, length, &cur_token,
907 boundary, &data_str, &data_size);
908 if (r == MAILIMF_NO_ERROR) {
909 /* do nothing */
910 }
911 else if (r == MAILIMF_ERROR_PARSE) {
912 break;
913 }
914 else {
915 res = r;
916 goto free;
917 }
918
919 bp_token = 0;
920
921
922 r = mailimf_optional_fields_parse(data_str, data_size,
923 &bp_token, &fields);
924 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
925 res = r;
926 goto free;
927 }
928
929 r = mailimf_crlf_parse(data_str, data_size, &bp_token);
930 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
931 mailimf_fields_free(fields);
932 res = r;
933 goto free;
934 }
935
936 mime_fields = NULL;
937 r = mailmime_fields_parse(fields, &mime_fields);
938 mailimf_fields_free(fields);
939 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
940 res = r;
941 goto free;
942 }
943
944 r = mailmime_parse_with_default(data_str, data_size,
945 &bp_token, default_subtype, NULL,
946 mime_fields, &mime_bp);
947 if (r == MAILIMF_NO_ERROR) {
948 r = clist_append(list, mime_bp);
949 if (r < 0) {
950 mailmime_free(mime_bp);
951 res = MAILIMF_ERROR_MEMORY;
952 goto free;
953 }
954 }
955 else if (r == MAILIMF_ERROR_PARSE) {
956 mailmime_fields_free(mime_fields);
957 break;
958 }
959 else {
960 mailmime_fields_free(mime_fields);
961 res = r;
962 goto free;
963 }
964
965 r = mailmime_multipart_next_parse(message, length, &cur_token);
966 if (r == MAILIMF_NO_ERROR) {
967 /* do nothing */
968 }
969 else if (r == MAILIMF_ERROR_PARSE) {
970 r = mailmime_multipart_close_parse(message, length, &cur_token);
971 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
972 res = r;
973 goto free;
974 }
975 break;
976 }
977 else {
978 res = r;
979 goto free;
980 }
981 }
982
983 epilogue_begin = length;
984 /* parse transport-padding */
985 while (1) {
986 r = mailmime_lwsp_parse(message, length, &cur_token);
987 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
988 res = r;
989 goto free;
990 }
991#if 0
992 if (r == MAILIMF_ERROR_PARSE)
993 break;
994#endif
995
996#if 0
997 before_crlf = cur_token;
998#endif
999 r = mailimf_crlf_parse(message, length, &cur_token);
1000 if (r == MAILIMF_NO_ERROR) {
1001 epilogue_begin = cur_token;
1002 break;
1003 }
1004 else if (r == MAILIMF_ERROR_PARSE) {
1005 /* do nothing */
1006 break;
1007 }
1008 else {
1009 res = r;
1010 goto free;
1011 }
1012 }
1013
1014 /* add preamble and epilogue */
1015
1016 epilogue_length = length - epilogue_begin;
1017
1018 if (preamble_length != 0) {
1019 preamble = mailmime_data_new(MAILMIME_DATA_TEXT,
1020 MAILMIME_MECHANISM_8BIT, 1,
1021 message + preamble_begin, preamble_length,
1022 NULL);
1023 if (preamble == NULL) {
1024 res = MAILIMF_ERROR_MEMORY;
1025 goto free;
1026 }
1027 }
1028
1029 if (epilogue_length != 0) {
1030 epilogue = mailmime_data_new(MAILMIME_DATA_TEXT,
1031 MAILMIME_MECHANISM_8BIT, 1,
1032 message + epilogue_begin, epilogue_length,
1033 NULL);
1034 if (epilogue == NULL) {
1035 res = MAILIMF_ERROR_MEMORY;
1036 goto free;
1037 }
1038 }
1039
1040 /* end of preamble and epilogue */
1041
1042 cur_token = length;
1043
1044 * result = list;
1045 * p_preamble = preamble;
1046 * p_epilogue = epilogue;
1047 * index = cur_token;
1048
1049 return MAILIMF_NO_ERROR;
1050
1051 free:
1052 if (epilogue != NULL)
1053 mailmime_data_free(epilogue);
1054 if (preamble != NULL)
1055 mailmime_data_free(preamble);
1056 clist_foreach(list, (clist_func) mailmime_free, NULL);
1057 clist_free(list);
1058 err:
1059 return res;
1060}
1061
1062enum {
1063 MAILMIME_DEFAULT_TYPE_TEXT_PLAIN,
1064 MAILMIME_DEFAULT_TYPE_MESSAGE
1065};
1066
1067
1068int mailmime_parse(const char * message, size_t length,
1069 size_t * index, struct mailmime ** result)
1070{
1071 struct mailmime * mime;
1072 int r;
1073 int res;
1074 struct mailmime_content * content_message;
1075 size_t cur_token;
1076 struct mailmime_fields * mime_fields;
1077 const char * data_str;
1078 size_t data_size;
1079 size_t bp_token;
1080
1081 cur_token = * index;
1082
1083 content_message = mailmime_get_content_message();
1084 if (content_message == NULL) {
1085 res = MAILIMF_ERROR_MEMORY;
1086 goto err;
1087 }
1088
1089#if 0
1090 mime_fields = mailmime_fields_new_with_data(content_message,
1091 NULL,
1092 NULL,
1093 NULL,
1094 NULL,
1095 NULL);
1096 if (mime_fields == NULL) {
1097 mailmime_content_free(content_message);
1098 res = MAILIMF_ERROR_MEMORY;
1099 goto err;
1100 }
1101#endif
1102 mime_fields = mailmime_fields_new_empty();
1103 if (mime_fields == NULL) {
1104 mailmime_content_free(content_message);
1105 res = MAILIMF_ERROR_MEMORY;
1106 goto err;
1107 }
1108
1109 data_str = message + cur_token;
1110 data_size = length - cur_token;
1111
1112 bp_token = 0;
1113 r = mailmime_parse_with_default(data_str, data_size,
1114 &bp_token, MAILMIME_DEFAULT_TYPE_TEXT_PLAIN,
1115 content_message, mime_fields, &mime);
1116 cur_token += bp_token;
1117 if (r != MAILIMF_NO_ERROR) {
1118 mailmime_fields_free(mime_fields);
1119 res = r;
1120 goto free;
1121 }
1122
1123 * index = cur_token;
1124 * result = mime;
1125
1126 return MAILIMF_NO_ERROR;
1127
1128 free:
1129 mailmime_fields_free(mime_fields);
1130 err:
1131 return res;
1132}
1133
1134
1135char * mailmime_extract_boundary(struct mailmime_content * content_type)
1136{
1137 char * boundary;
1138
1139 boundary = mailmime_content_param_get(content_type, "boundary");
1140
1141 if (boundary != NULL) {
1142 int len;
1143 char * new_boundary;
1144
1145 len = strlen(boundary);
1146 new_boundary = malloc(len + 1);
1147 if (new_boundary == NULL)
1148 return NULL;
1149
1150 if (boundary[0] == '"') {
1151 strncpy(new_boundary, boundary + 1, len - 2);
1152 new_boundary[len - 2] = 0;
1153 }
1154 else
1155 strcpy(new_boundary, boundary);
1156
1157 boundary = new_boundary;
1158 }
1159
1160 return boundary;
1161}
1162
1163static void remove_unparsed_mime_headers(struct mailimf_fields * fields)
1164{
1165 clistiter * cur;
1166
1167 cur = clist_begin(fields->fld_list);
1168 while (cur != NULL) {
1169 struct mailimf_field * field;
1170 int delete;
1171
1172 field = clist_content(cur);
1173
1174 switch (field->fld_type) {
1175 case MAILIMF_FIELD_OPTIONAL_FIELD:
1176 delete = 0;
1177 if (strncasecmp(field->fld_data.fld_optional_field->fld_name,
1178 "Content-", 8) == 0) {
1179 char * name;
1180
1181 name = field->fld_data.fld_optional_field->fld_name + 8;
1182 if ((strcasecmp(name, "Type") == 0)
1183 || (strcasecmp(name, "Transfer-Encoding") == 0)
1184 || (strcasecmp(name, "ID") == 0)
1185 || (strcasecmp(name, "Description") == 0)
1186 || (strcasecmp(name, "Disposition") == 0)
1187 || (strcasecmp(name, "Language") == 0)) {
1188 delete = 1;
1189 }
1190 }
1191 else if (strcasecmp(field->fld_data.fld_optional_field->fld_name,
1192 "MIME-Version") == 0) {
1193 delete = 1;
1194 }
1195
1196 if (delete) {
1197 cur = clist_delete(fields->fld_list, cur);
1198 mailimf_field_free(field);
1199 }
1200 else {
1201 cur = clist_next(cur);
1202 }
1203 break;
1204
1205 default:
1206 cur = clist_next(cur);
1207 }
1208 }
1209}
1210
1211static int mailmime_parse_with_default(const char * message, size_t length,
1212 size_t * index, int default_type,
1213 struct mailmime_content * content_type,
1214 struct mailmime_fields * mime_fields,
1215 struct mailmime ** result)
1216{
1217 size_t cur_token;
1218
1219 int body_type;
1220
1221 int encoding;
1222 struct mailmime_data * body;
1223 char * boundary;
1224 struct mailimf_fields * fields;
1225 clist * list;
1226 struct mailmime * msg_mime;
1227
1228 struct mailmime * mime;
1229
1230 int r;
1231 int res;
1232 struct mailmime_data * preamble;
1233 struct mailmime_data * epilogue;
1234
1235 /*
1236 note that when this function is called, content type is always detached,
1237 even if the function fails
1238 */
1239
1240 preamble = NULL;
1241 epilogue = NULL;
1242
1243 cur_token = * index;
1244
1245 /* get content type */
1246
1247 if (content_type == NULL) {
1248 if (mime_fields != NULL) {
1249 clistiter * cur;
1250
1251 for(cur = clist_begin(mime_fields->fld_list) ; cur != NULL ;
1252 cur = clist_next(cur)) {
1253 struct mailmime_field * field;
1254
1255 field = clist_content(cur);
1256 if (field->fld_type == MAILMIME_FIELD_TYPE) {
1257 content_type = field->fld_data.fld_content;
1258
1259 /* detach content type from list */
1260 field->fld_data.fld_content = NULL;
1261 clist_delete(mime_fields->fld_list, cur);
1262 mailmime_field_free(field);
1263 /*
1264 there may be a leak due to the detached content type
1265 in case the function fails
1266 */
1267 break;
1268 }
1269 }
1270 }
1271 }
1272
1273 /* set default type if no content type */
1274
1275 if (content_type == NULL) {
1276 /* content_type is detached, in any case, we will have to free it */
1277 if (default_type == MAILMIME_DEFAULT_TYPE_TEXT_PLAIN) {
1278 content_type = mailmime_get_content_text();
1279 if (content_type == NULL) {
1280 res = MAILIMF_ERROR_MEMORY;
1281 goto err;
1282 }
1283 }
1284 else /* message */ {
1285 body_type = MAILMIME_MESSAGE;
1286
1287 content_type = mailmime_get_content_message();
1288 if (content_type == NULL) {
1289 res = MAILIMF_ERROR_MEMORY;
1290 goto err;
1291 }
1292 }
1293 }
1294
1295 /* get the body type */
1296
1297 boundary = NULL; /* XXX - removes a gcc warning */
1298
1299 switch (content_type->ct_type->tp_type) {
1300 case MAILMIME_TYPE_COMPOSITE_TYPE:
1301 switch (content_type->ct_type->tp_data.tp_composite_type->ct_type) {
1302 case MAILMIME_COMPOSITE_TYPE_MULTIPART:
1303 boundary = mailmime_extract_boundary(content_type);
1304
1305 if (boundary == NULL)
1306 body_type = MAILMIME_SINGLE;
1307 else
1308 body_type = MAILMIME_MULTIPLE;
1309 break;
1310
1311 case MAILMIME_COMPOSITE_TYPE_MESSAGE:
1312
1313 if (strcasecmp(content_type->ct_subtype, "rfc822") == 0)
1314 body_type = MAILMIME_MESSAGE;
1315 else
1316 body_type = MAILMIME_SINGLE;
1317 break;
1318
1319 default:
1320 res = MAILIMF_ERROR_INVAL;
1321 goto free_content;
1322 }
1323 break;
1324
1325 default: /* MAILMIME_TYPE_DISCRETE_TYPE */
1326 body_type = MAILMIME_SINGLE;
1327 break;
1328 }
1329
1330 /* set body */
1331
1332 if (mime_fields != NULL)
1333 encoding = mailmime_transfer_encoding_get(mime_fields);
1334 else
1335 encoding = MAILMIME_MECHANISM_8BIT;
1336
1337 cur_token = * index;
1338 body = mailmime_data_new(MAILMIME_DATA_TEXT, encoding, 1,
1339 message + cur_token, length - cur_token,
1340 NULL);
1341 if (body == NULL) {
1342 res = MAILIMF_ERROR_MEMORY;
1343 goto free_content;
1344 }
1345
1346 /* in case of composite, parse the sub-part(s) */
1347
1348 list = NULL;
1349 msg_mime = NULL;
1350 fields = NULL;
1351
1352 switch (body_type) {
1353 case MAILMIME_MESSAGE:
1354 {
1355 struct mailmime_fields * submime_fields;
1356
1357 r = mailimf_envelope_and_optional_fields_parse(message, length,
1358 &cur_token, &fields);
1359 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
1360 res = r;
1361 goto free_content;
1362 }
1363
1364 r = mailimf_crlf_parse(message, length, &cur_token);
1365 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
1366 mailimf_fields_free(fields);
1367 res = r;
1368 goto free_content;
1369 }
1370
1371 submime_fields = NULL;
1372 r = mailmime_fields_parse(fields, &submime_fields);
1373 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
1374 mailimf_fields_free(fields);
1375 res = r;
1376 goto free_content;
1377 }
1378
1379 remove_unparsed_mime_headers(fields);
1380
1381 r = mailmime_parse_with_default(message, length,
1382 &cur_token, MAILMIME_DEFAULT_TYPE_TEXT_PLAIN,
1383 NULL, submime_fields, &msg_mime);
1384 if (r == MAILIMF_NO_ERROR) {
1385 /* do nothing */
1386 }
1387 else if (r == MAILIMF_ERROR_PARSE) {
1388 mailmime_fields_free(mime_fields);
1389 msg_mime = NULL;
1390 }
1391 else {
1392 mailmime_fields_free(mime_fields);
1393 res = r;
1394 goto free_content;
1395 }
1396 }
1397
1398 break;
1399
1400 case MAILMIME_MULTIPLE:
1401 {
1402 int default_subtype;
1403
1404 default_subtype = MAILMIME_DEFAULT_TYPE_TEXT_PLAIN;
1405 if (content_type != NULL)
1406 if (strcasecmp(content_type->ct_subtype, "digest") == 0)
1407 default_subtype = MAILMIME_DEFAULT_TYPE_MESSAGE;
1408
1409 cur_token = * index;
1410 r = mailmime_multipart_body_parse(message, length,
1411 &cur_token, boundary,
1412 default_subtype,
1413 &list, &preamble, &epilogue);
1414 if (r == MAILIMF_NO_ERROR) {
1415 /* do nothing */
1416 }
1417 else if (r == MAILIMF_ERROR_PARSE) {
1418 list = clist_new();
1419 if (list == NULL) {
1420 res = MAILIMF_ERROR_MEMORY;
1421 goto free_content;
1422 }
1423 }
1424 else {
1425 res = r;
1426 goto free_content;
1427 }
1428
1429 free(boundary);
1430 }
1431 break;
1432
1433 default: /* MAILMIME_SINGLE */
1434 /* do nothing */
1435 break;
1436 }
1437
1438 mime = mailmime_new(body_type, message, length,
1439 mime_fields, content_type,
1440 body, preamble, /* preamble */
1441 epilogue, /* epilogue */
1442 list, fields, msg_mime);
1443 if (mime == NULL) {
1444 res = MAILIMF_ERROR_MEMORY;
1445 goto free;
1446 }
1447
1448 * result = mime;
1449 * index = length;
1450
1451 return MAILIMF_NO_ERROR;
1452
1453 free:
1454 if (epilogue != NULL)
1455 mailmime_data_free(epilogue);
1456 if (preamble != NULL)
1457 mailmime_data_free(preamble);
1458 if (msg_mime != NULL)
1459 mailmime_free(msg_mime);
1460 if (list != NULL) {
1461 clist_foreach(list, (clist_func) mailmime_free, NULL);
1462 clist_free(list);
1463 }
1464 free_content:
1465 mailmime_content_free(content_type);
1466 err:
1467 return res;
1468}
1469
1470static int mailmime_get_section_list(struct mailmime * mime,
1471 clistiter * list, struct mailmime ** result)
1472{
1473 uint32_t id;
1474 struct mailmime * data;
1475 struct mailmime * submime;
1476
1477 if (list == NULL) {
1478 * result = mime;
1479 return MAILIMF_NO_ERROR;
1480 }
1481
1482 id = * ((uint32_t *) clist_content(list));
1483
1484 data = NULL;
1485 switch (mime->mm_type) {
1486 case MAILMIME_SINGLE:
1487 return MAILIMF_ERROR_INVAL;
1488
1489 case MAILMIME_MULTIPLE:
1490 data = clist_nth_data(mime->mm_data.mm_multipart.mm_mp_list, id - 1);
1491 if (data == NULL)
1492 return MAILIMF_ERROR_INVAL;
1493
1494 if (clist_next(list) != NULL)
1495 return mailmime_get_section_list(data, clist_next(list), result);
1496 else {
1497 * result = data;
1498 return MAILIMF_NO_ERROR;
1499 }
1500
1501 case MAILMIME_MESSAGE:
1502 submime = mime->mm_data.mm_message.mm_msg_mime;
1503 switch (submime->mm_type) {
1504 case MAILMIME_MULTIPLE:
1505 data = clist_nth_data(submime->mm_data.mm_multipart.mm_mp_list, id - 1);
1506 if (data == NULL)
1507 return MAILIMF_ERROR_INVAL;
1508 return mailmime_get_section_list(data, clist_next(list), result);
1509
1510 default:
1511 if (id != 1)
1512 return MAILIMF_ERROR_INVAL;
1513
1514 data = submime;
1515 if (data == NULL)
1516 return MAILIMF_ERROR_INVAL;
1517
1518 return mailmime_get_section_list(data, clist_next(list), result);
1519 }
1520 break;
1521
1522 default:
1523 return MAILIMF_ERROR_INVAL;
1524 }
1525}
1526
1527int mailmime_get_section(struct mailmime * mime,
1528 struct mailmime_section * section,
1529 struct mailmime ** result)
1530{
1531 return mailmime_get_section_list(mime,
1532 clist_begin(section->sec_list), result);
1533}
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549/* ************************************************************************* */
1550/* MIME part decoding */
1551
1552static inline signed char get_base64_value(char ch)
1553{
1554 if ((ch >= 'A') && (ch <= 'Z'))
1555 return ch - 'A';
1556 if ((ch >= 'a') && (ch <= 'z'))
1557 return ch - 'a' + 26;
1558 if ((ch >= '0') && (ch <= '9'))
1559 return ch - '0' + 52;
1560 switch (ch) {
1561 case '+':
1562 return 62;
1563 case '/':
1564 return 63;
1565 case '=': /* base64 padding */
1566 return -1;
1567 default:
1568 return -1;
1569 }
1570}
1571
1572int mailmime_base64_body_parse(const char * message, size_t length,
1573 size_t * index, char ** result,
1574 size_t * result_len)
1575{
1576 size_t cur_token;
1577 size_t i;
1578 char chunk[4];
1579 int chunk_index;
1580 char out[3];
1581 MMAPString * mmapstr;
1582 int res;
1583 int r;
1584 size_t written;
1585
1586 cur_token = * index;
1587 chunk_index = 0;
1588 written = 0;
1589
1590 mmapstr = mmap_string_sized_new((length - cur_token) * 3 / 4);
1591 if (mmapstr == NULL) {
1592 res = MAILIMF_ERROR_MEMORY;
1593 goto err;
1594 }
1595
1596 i = 0;
1597 while (1) {
1598 signed char value;
1599
1600 value = -1;
1601 while (value == -1) {
1602
1603 if (cur_token >= length)
1604 break;
1605
1606 value = get_base64_value(message[cur_token]);
1607 cur_token ++;
1608 }
1609
1610 if (value == -1)
1611 break;
1612
1613 chunk[chunk_index] = value;
1614 chunk_index ++;
1615
1616 if (chunk_index == 4) {
1617 out[0] = (chunk[0] << 2) | (chunk[1] >> 4);
1618 out[1] = (chunk[1] << 4) | (chunk[2] >> 2);
1619 out[2] = (chunk[2] << 6) | (chunk[3]);
1620
1621 chunk[0] = 0;
1622 chunk[1] = 0;
1623 chunk[2] = 0;
1624 chunk[3] = 0;
1625
1626 chunk_index = 0;
1627
1628 if (mmap_string_append_len(mmapstr, out, 3) == NULL) {
1629 res = MAILIMF_ERROR_MEMORY;
1630 goto free;
1631 }
1632 written += 3;
1633 }
1634 }
1635
1636 if (chunk_index != 0) {
1637 size_t len;
1638
1639 len = 0;
1640 out[0] = (chunk[0] << 2) | (chunk[1] >> 4);
1641 len ++;
1642
1643 if (chunk_index >= 3) {
1644 out[1] = (chunk[1] << 4) | (chunk[2] >> 2);
1645 len ++;
1646 }
1647
1648 if (mmap_string_append_len(mmapstr, out, len) == NULL) {
1649 res = MAILIMF_ERROR_MEMORY;
1650 goto free;
1651 }
1652 written += len;
1653 }
1654
1655 r = mmap_string_ref(mmapstr);
1656 if (r < 0) {
1657 res = MAILIMF_ERROR_MEMORY;
1658 goto free;
1659 }
1660
1661 * index = cur_token;
1662 * result = mmapstr->str;
1663 * result_len = written;
1664
1665 return MAILIMF_NO_ERROR;
1666
1667 free:
1668 mmap_string_free(mmapstr);
1669 err:
1670 return res;
1671}
1672
1673
1674
1675static inline int hexa_to_char(char hexdigit)
1676{
1677 if ((hexdigit >= '0') && (hexdigit <= '9'))
1678 return hexdigit - '0';
1679 if ((hexdigit >= 'a') && (hexdigit <= 'f'))
1680 return hexdigit - 'a' + 10;
1681 if ((hexdigit >= 'A') && (hexdigit <= 'F'))
1682 return hexdigit - 'A' + 10;
1683 return 0;
1684}
1685
1686static inline char to_char(const char * hexa)
1687{
1688 return (hexa_to_char(hexa[0]) << 4) | hexa_to_char(hexa[1]);
1689}
1690
1691enum {
1692 STATE_NORMAL,
1693 STATE_CODED,
1694 STATE_OUT,
1695 STATE_CR,
1696};
1697
1698
1699static int write_decoded_qp(MMAPString * mmapstr,
1700 const char * start, size_t count)
1701{
1702 if (mmap_string_append_len(mmapstr, start, count) == NULL)
1703 return MAILIMF_ERROR_MEMORY;
1704
1705 return MAILIMF_NO_ERROR;
1706}
1707
1708
1709#define WRITE_MAX_QP 512
1710
1711int mailmime_quoted_printable_body_parse(const char * message, size_t length,
1712 size_t * index, char ** result,
1713 size_t * result_len, int in_header)
1714{
1715 size_t cur_token;
1716 int state;
1717 int r;
1718 char ch;
1719 size_t count;
1720 const char * start;
1721 MMAPString * mmapstr;
1722 int res;
1723 size_t written;
1724
1725 state = STATE_NORMAL;
1726 cur_token = * index;
1727
1728 count = 0;
1729 start = message + cur_token;
1730 written = 0;
1731
1732 mmapstr = mmap_string_sized_new(length - cur_token);
1733 if (mmapstr == NULL) {
1734 res = MAILIMF_ERROR_MEMORY;
1735 goto err;
1736 }
1737
1738#if 0
1739 if (length >= 1) {
1740 if (message[length - 1] == '\n') {
1741 length --;
1742 if (length >= 1)
1743 if (message[length - 1] == '\r') {
1744 length --;
1745 }
1746 }
1747 }
1748#endif
1749
1750 while (state != STATE_OUT) {
1751
1752 if (cur_token >= length) {
1753 state = STATE_OUT;
1754 break;
1755 }
1756
1757 switch (state) {
1758
1759 case STATE_CODED:
1760
1761 if (count > 0) {
1762 r = write_decoded_qp(mmapstr, start, count);
1763 if (r != MAILIMF_NO_ERROR) {
1764 res = r;
1765 goto free;
1766 }
1767 written += count;
1768 count = 0;
1769 }
1770
1771 switch (message[cur_token]) {
1772 case '=':
1773 if (cur_token + 1 >= length) {
1774 /* error but ignore it */
1775 state = STATE_NORMAL;
1776 start = message + cur_token;
1777 cur_token ++;
1778 count ++;
1779 break;
1780 }
1781
1782 switch (message[cur_token + 1]) {
1783
1784 case '\n':
1785 cur_token += 2;
1786
1787 start = message + cur_token;
1788
1789 state = STATE_NORMAL;
1790 break;
1791
1792 case '\r':
1793 if (cur_token + 2 >= length) {
1794 state = STATE_OUT;
1795 break;
1796 }
1797
1798 if (message[cur_token + 2] == '\n')
1799 cur_token += 3;
1800 else
1801 cur_token += 2;
1802
1803 start = message + cur_token;
1804
1805 state = STATE_NORMAL;
1806
1807 break;
1808
1809 default:
1810 if (cur_token + 2 >= length) {
1811 /* error but ignore it */
1812 cur_token ++;
1813
1814 start = message + cur_token;
1815
1816 count ++;
1817 state = STATE_NORMAL;
1818 break;
1819 }
1820
1821#if 0
1822 /* flush before writing additionnal information */
1823 r = write_decoded_qp(mmapstr, start, count);
1824 if (r != MAILIMF_NO_ERROR) {
1825 res = r;
1826 goto free;
1827 }
1828 written += count;
1829 count = 0;
1830#endif
1831
1832 ch = to_char(message + cur_token + 1);
1833
1834 if (mmap_string_append_c(mmapstr, ch) == NULL) {
1835 res = MAILIMF_ERROR_MEMORY;
1836 goto free;
1837 }
1838
1839 cur_token += 3;
1840 written ++;
1841
1842 start = message + cur_token;
1843
1844 state = STATE_NORMAL;
1845 break;
1846 }
1847 break;
1848 }
1849 break; /* end of STATE_ENCODED */
1850
1851 case STATE_NORMAL:
1852
1853 switch (message[cur_token]) {
1854
1855 case '=':
1856 state = STATE_CODED;
1857 break;
1858
1859 case '\n':
1860 /* flush before writing additionnal information */
1861 if (count > 0) {
1862 r = write_decoded_qp(mmapstr, start, count);
1863 if (r != MAILIMF_NO_ERROR) {
1864 res = r;
1865 goto free;
1866 }
1867 written += count;
1868
1869 count = 0;
1870 }
1871
1872 r = write_decoded_qp(mmapstr, "\r\n", 2);
1873 if (r != MAILIMF_NO_ERROR) {
1874 res = r;
1875 goto free;
1876 }
1877 written += 2;
1878 cur_token ++;
1879 start = message + cur_token;
1880 break;
1881
1882 case '\r':
1883 state = STATE_CR;
1884 cur_token ++;
1885 break;
1886
1887 case '_':
1888 if (in_header) {
1889 if (count > 0) {
1890 r = write_decoded_qp(mmapstr, start, count);
1891 if (r != MAILIMF_NO_ERROR) {
1892 res = r;
1893 goto free;
1894 }
1895 written += count;
1896 count = 0;
1897 }
1898
1899 if (mmap_string_append_c(mmapstr, ' ') == NULL) {
1900 res = MAILIMF_ERROR_MEMORY;
1901 goto free;
1902 }
1903
1904 written ++;
1905 cur_token ++;
1906 start = message + cur_token;
1907
1908 break;
1909 }
1910 /* WARINING : must be followed by switch default action */
1911
1912 default:
1913 if (count >= WRITE_MAX_QP) {
1914 r = write_decoded_qp(mmapstr, start, count);
1915 if (r != MAILIMF_NO_ERROR) {
1916 res = r;
1917 goto free;
1918 }
1919 written += count;
1920 count = 0;
1921 start = message + cur_token;
1922 }
1923
1924 count ++;
1925 cur_token ++;
1926 break;
1927 }
1928 break; /* end of STATE_NORMAL */
1929
1930 case STATE_CR:
1931 switch (message[cur_token]) {
1932
1933 case '\n':
1934 /* flush before writing additionnal information */
1935 if (count > 0) {
1936 r = write_decoded_qp(mmapstr, start, count);
1937 if (r != MAILIMF_NO_ERROR) {
1938 res = r;
1939 goto free;
1940 }
1941 written += count;
1942 count = 0;
1943 }
1944
1945 r = write_decoded_qp(mmapstr, "\r\n", 2);
1946 if (r != MAILIMF_NO_ERROR) {
1947 res = r;
1948 goto free;
1949 }
1950 written += 2;
1951 cur_token ++;
1952 start = message + cur_token;
1953 state = STATE_NORMAL;
1954 break;
1955
1956 default:
1957 /* flush before writing additionnal information */
1958 if (count > 0) {
1959 r = write_decoded_qp(mmapstr, start, count);
1960 if (r != MAILIMF_NO_ERROR) {
1961 res = r;
1962 goto free;
1963 }
1964 written += count;
1965 count = 0;
1966 }
1967
1968 start = message + cur_token;
1969
1970 r = write_decoded_qp(mmapstr, "\r\n", 2);
1971 if (r != MAILIMF_NO_ERROR) {
1972 res = r;
1973 goto free;
1974 }
1975 written += 2;
1976 state = STATE_NORMAL;
1977 }
1978 break; /* end of STATE_CR */
1979 }
1980 }
1981
1982 if (count > 0) {
1983 r = write_decoded_qp(mmapstr, start, count);
1984 if (r != MAILIMF_NO_ERROR) {
1985 res = r;
1986 goto free;
1987 }
1988 written += count;
1989 count = 0;
1990 }
1991
1992 r = mmap_string_ref(mmapstr);
1993 if (r < 0) {
1994 res = MAILIMF_ERROR_MEMORY;
1995 goto free;
1996 }
1997
1998 * index = cur_token;
1999 * result = mmapstr->str;
2000 * result_len = written;
2001
2002 return MAILIMF_NO_ERROR;
2003
2004 free:
2005 mmap_string_free(mmapstr);
2006 err:
2007 return res;
2008}
2009
2010int mailmime_binary_body_parse(const char * message, size_t length,
2011 size_t * index, char ** result,
2012 size_t * result_len)
2013{
2014 MMAPString * mmapstr;
2015 size_t cur_token;
2016 int r;
2017 int res;
2018
2019 cur_token = * index;
2020
2021 if (length >= 1) {
2022 if (message[length - 1] == '\n') {
2023 length --;
2024 if (length >= 1)
2025 if (message[length - 1] == '\r')
2026 length --;
2027 }
2028 }
2029
2030 mmapstr = mmap_string_new_len(message + cur_token, length - cur_token);
2031 if (mmapstr == NULL) {
2032 res = MAILIMF_ERROR_MEMORY;
2033 goto err;
2034 }
2035
2036 r = mmap_string_ref(mmapstr);
2037 if (r < 0) {
2038 res = MAILIMF_ERROR_MEMORY;
2039 goto free;
2040 }
2041
2042 * index = length;
2043 * result = mmapstr->str;
2044 * result_len = length - cur_token;
2045
2046 return MAILIMF_NO_ERROR;
2047
2048 free:
2049 mmap_string_free(mmapstr);
2050 err:
2051 return res;
2052}
2053
2054
2055int mailmime_part_parse(const char * message, size_t length,
2056 size_t * index,
2057 int encoding, char ** result, size_t * result_len)
2058{
2059 switch (encoding) {
2060 case MAILMIME_MECHANISM_BASE64:
2061 return mailmime_base64_body_parse(message, length, index,
2062 result, result_len);
2063
2064 case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
2065 return mailmime_quoted_printable_body_parse(message, length, index,
2066 result, result_len, FALSE);
2067
2068 case MAILMIME_MECHANISM_7BIT:
2069 case MAILMIME_MECHANISM_8BIT:
2070 case MAILMIME_MECHANISM_BINARY:
2071 default:
2072 return mailmime_binary_body_parse(message, length, index,
2073 result, result_len);
2074 }
2075}
2076
2077int mailmime_get_section_id(struct mailmime * mime,
2078 struct mailmime_section ** result)
2079{
2080 clist * list;
2081 int res;
2082 struct mailmime_section * section_id;
2083 int r;
2084
2085 if (mime->mm_parent == NULL) {
2086 list = clist_new();
2087 if (list == NULL) {
2088 res = MAILIMF_ERROR_MEMORY;
2089 goto err;
2090 }
2091
2092 section_id = mailmime_section_new(list);
2093 if (section_id == NULL) {
2094 res = MAILIMF_ERROR_MEMORY;
2095 goto err;
2096 }
2097 }
2098 else {
2099 uint32_t id;
2100 uint32_t * p_id;
2101 clistiter * cur;
2102 struct mailmime * parent;
2103
2104 r = mailmime_get_section_id(mime->mm_parent, &section_id);
2105 if (r != MAILIMF_NO_ERROR) {
2106 res = r;
2107 goto err;
2108 }
2109
2110 parent = mime->mm_parent;
2111 switch (parent->mm_type) {
2112 case MAILMIME_MULTIPLE:
2113 id = 1;
2114 for(cur = clist_begin(parent->mm_data.mm_multipart.mm_mp_list) ;
2115 cur != NULL ; cur = clist_next(cur)) {
2116 if (clist_content(cur) == mime)
2117 break;
2118 id ++;
2119 }
2120
2121 p_id = malloc(sizeof(* p_id));
2122 if (p_id == NULL) {
2123 res = MAILIMF_ERROR_MEMORY;
2124 goto free;
2125 }
2126 * p_id = id;
2127
2128 r = clist_append(section_id->sec_list, p_id);
2129 if (r < 0) {
2130 free(p_id);
2131 res = MAILIMF_ERROR_MEMORY;
2132 goto free;
2133 }
2134 break;
2135
2136 case MAILMIME_MESSAGE:
2137 if ((mime->mm_type == MAILMIME_SINGLE) ||
2138 (mime->mm_type == MAILMIME_MESSAGE)) {
2139 p_id = malloc(sizeof(* p_id));
2140 if (p_id == NULL) {
2141 res = MAILIMF_ERROR_MEMORY;
2142 goto free;
2143 }
2144 * p_id = 1;
2145
2146 r = clist_append(section_id->sec_list, p_id);
2147 if (r < 0) {
2148 free(p_id);
2149 res = MAILIMF_ERROR_MEMORY;
2150 goto free;
2151 }
2152 }
2153 }
2154 }
2155
2156 * result = section_id;
2157
2158 return MAILIMF_NO_ERROR;
2159
2160 free:
2161 mailmime_section_free(section_id);
2162 err:
2163 return res;
2164}
diff --git a/kmicromail/libetpan/mime/mailmime_content.h b/kmicromail/libetpan/mime/mailmime_content.h
new file mode 100644
index 0000000..df4b232
--- a/dev/null
+++ b/kmicromail/libetpan/mime/mailmime_content.h
@@ -0,0 +1,89 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMIME_CONTENT_H
37
38#define MAILMIME_CONTENT_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailmime_types.h>
45
46char * mailmime_content_charset_get(struct mailmime_content * content);
47
48char * mailmime_content_param_get(struct mailmime_content * content,
49 char * name);
50
51int mailmime_parse(const char * message, size_t length,
52 size_t * index, struct mailmime ** result);
53
54int mailmime_get_section(struct mailmime * mime,
55 struct mailmime_section * section,
56 struct mailmime ** result);
57
58
59char * mailmime_extract_boundary(struct mailmime_content * content_type);
60
61
62/* decode */
63
64int mailmime_base64_body_parse(const char * message, size_t length,
65 size_t * index, char ** result,
66 size_t * result_len);
67
68int mailmime_quoted_printable_body_parse(const char * message, size_t length,
69 size_t * index, char ** result,
70 size_t * result_len, int in_header);
71
72
73int mailmime_binary_body_parse(const char * message, size_t length,
74 size_t * index, char ** result,
75 size_t * result_len);
76
77int mailmime_part_parse(const char * message, size_t length,
78 size_t * index,
79 int encoding, char ** result, size_t * result_len);
80
81
82int mailmime_get_section_id(struct mailmime * mime,
83 struct mailmime_section ** result);
84
85#ifdef __cplusplus
86}
87#endif
88
89#endif
diff --git a/kmicromail/libetpan/mime/mailmime_decode.c b/kmicromail/libetpan/mime/mailmime_decode.c
new file mode 100644
index 0000000..3025dcb
--- a/dev/null
+++ b/kmicromail/libetpan/mime/mailmime_decode.c
@@ -0,0 +1,533 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36/*
37 RFC 2047 : MIME (Multipurpose Internet Mail Extensions) Part Three:
38 Message Header Extensions for Non-ASCII Text
39*/
40
41#include "mailmime_decode.h"
42
43#include <ctype.h>
44#include <unistd.h>
45#include <sys/mman.h>
46#include <string.h>
47#include <stdlib.h>
48
49#include "mailmime_content.h"
50
51#include "charconv.h"
52#include "mmapstring.h"
53#include "mailimf.h"
54
55#ifndef TRUE
56#define TRUE 1
57#endif
58
59#ifndef FALSE
60#define FALSE 0
61#endif
62
63static int mailmime_charset_parse(const char * message, size_t length,
64 size_t * index, char ** charset);
65
66enum {
67 MAILMIME_ENCODING_B,
68 MAILMIME_ENCODING_Q
69};
70
71static int mailmime_encoding_parse(const char * message, size_t length,
72 size_t * index, int * result);
73
74static int mailmime_etoken_parse(const char * message, size_t length,
75 size_t * index, char ** result);
76
77static int
78mailmime_non_encoded_word_parse(const char * message, size_t length,
79 size_t * index,
80 char ** result);
81
82static int
83mailmime_encoded_word_parse(const char * message, size_t length,
84 size_t * index,
85 struct mailmime_encoded_word ** result);
86
87
88enum {
89 TYPE_ERROR,
90 TYPE_WORD,
91 TYPE_ENCODED_WORD,
92};
93
94int mailmime_encoded_phrase_parse(const char * default_fromcode,
95 const char * message, size_t length,
96 size_t * index, const char * tocode,
97 char ** result)
98{
99 MMAPString * gphrase;
100 struct mailmime_encoded_word * word;
101 int first;
102 size_t cur_token;
103 int r;
104 int res;
105 char * str;
106 char * wordutf8;
107 int type;
108
109 cur_token = * index;
110
111 gphrase = mmap_string_new("");
112 if (gphrase == NULL) {
113 res = MAILIMF_ERROR_MEMORY;
114 goto err;
115 }
116
117 first = TRUE;
118
119 type = TYPE_ERROR; /* XXX - removes a gcc warning */
120
121 while (1) {
122
123 r = mailmime_encoded_word_parse(message, length, &cur_token, &word);
124 if (r == MAILIMF_NO_ERROR) {
125 if (!first) {
126 if (type != TYPE_ENCODED_WORD) {
127 if (mmap_string_append_c(gphrase, ' ') == NULL) {
128 mailmime_encoded_word_free(word);
129 res = MAILIMF_ERROR_MEMORY;
130 goto free;
131 }
132 }
133 }
134 type = TYPE_ENCODED_WORD;
135 wordutf8 = NULL;
136 r = charconv(tocode, word->wd_charset, word->wd_text,
137 strlen(word->wd_text), &wordutf8);
138 switch (r) {
139 case MAIL_CHARCONV_ERROR_MEMORY:
140 mailmime_encoded_word_free(word);
141 res = MAILIMF_ERROR_MEMORY;
142 goto free;
143
144 case MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET:
145 case MAIL_CHARCONV_ERROR_CONV:
146 mailmime_encoded_word_free(word);
147 res = MAILIMF_ERROR_PARSE;
148 goto free;
149 }
150
151 if (wordutf8 != NULL) {
152 if (mmap_string_append(gphrase, wordutf8) == NULL) {
153 mailmime_encoded_word_free(word);
154 free(wordutf8);
155 res = MAILIMF_ERROR_MEMORY;
156 goto free;
157 }
158 free(wordutf8);
159 }
160 mailmime_encoded_word_free(word);
161 first = FALSE;
162 }
163 else if (r == MAILIMF_ERROR_PARSE) {
164 /* do nothing */
165 }
166 else {
167 res = r;
168 goto free;
169 }
170
171 if (r == MAILIMF_ERROR_PARSE) {
172 char * raw_word;
173
174 r = mailmime_non_encoded_word_parse(message, length,
175 &cur_token, &raw_word);
176 if (r == MAILIMF_NO_ERROR) {
177 if (!first) {
178 if (mmap_string_append_c(gphrase, ' ') == NULL) {
179 free(raw_word);
180 res = MAILIMF_ERROR_MEMORY;
181 goto free;
182 }
183 }
184 type = TYPE_WORD;
185
186 wordutf8 = NULL;
187 r = charconv(tocode, default_fromcode, raw_word,
188 strlen(raw_word), &wordutf8);
189
190 if (wordutf8 != NULL) {
191 if (mmap_string_append(gphrase, wordutf8) == NULL) {
192 free(wordutf8);
193 free(raw_word);
194 res = MAILIMF_ERROR_MEMORY;
195 goto free;
196 }
197
198 free(wordutf8);
199 }
200 free(raw_word);
201 first = FALSE;
202 }
203 else if (r == MAILIMF_ERROR_PARSE) {
204 break;
205 }
206 else {
207 res = r;
208 goto free;
209 }
210 }
211 }
212
213 if (first) {
214 res = MAILIMF_ERROR_PARSE;
215 goto free;
216 }
217
218 str = strdup(gphrase->str);
219 if (str == NULL) {
220 res = MAILIMF_ERROR_MEMORY;
221 goto free;
222 }
223 mmap_string_free(gphrase);
224
225 * result = str;
226 * index = cur_token;
227
228 return MAILIMF_NO_ERROR;
229
230 free:
231 mmap_string_free(gphrase);
232 err:
233 return res;
234}
235
236static int
237mailmime_non_encoded_word_parse(const char * message, size_t length,
238 size_t * index,
239 char ** result)
240{
241 int end;
242 size_t cur_token;
243 int res;
244 char * text;
245 int r;
246 size_t begin;
247
248 cur_token = * index;
249
250 r = mailimf_fws_parse(message, length, &cur_token);
251 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
252 res = r;
253 goto err;
254 }
255
256 begin = cur_token;
257
258 end = FALSE;
259 while (1) {
260 if (cur_token >= length)
261 break;
262
263 switch (message[cur_token]) {
264 case ' ':
265 case '\t':
266 case '\r':
267 case '\n':
268 end = TRUE;
269 break;
270 }
271
272 if (end)
273 break;
274
275 cur_token ++;
276 }
277
278 if (cur_token - begin == 0) {
279 res = MAILIMF_ERROR_PARSE;
280 goto err;
281 }
282
283 text = malloc(cur_token - begin + 1);
284 if (text == NULL) {
285 res = MAILIMF_ERROR_MEMORY;
286 goto err;
287 }
288
289 memcpy(text, message + begin, cur_token - begin);
290 text[cur_token - begin] = '\0';
291
292 * index = cur_token;
293 * result = text;
294
295 return MAILIMF_NO_ERROR;
296
297 err:
298 return res;
299}
300
301static int mailmime_encoded_word_parse(const char * message, size_t length,
302 size_t * index,
303 struct mailmime_encoded_word ** result)
304{
305 size_t cur_token;
306 char * charset;
307 int encoding;
308 char * text;
309 size_t end_encoding;
310 char * decoded;
311 size_t decoded_len;
312 struct mailmime_encoded_word * ew;
313 int r;
314 int res;
315 int opening_quote;
316 int end;
317
318 cur_token = * index;
319
320 r = mailimf_fws_parse(message, length, &cur_token);
321 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
322 res = r;
323 goto err;
324 }
325
326 opening_quote = FALSE;
327 r = mailimf_char_parse(message, length, &cur_token, '\"');
328 if (r == MAILIMF_NO_ERROR) {
329 opening_quote = TRUE;
330 }
331 else if (r == MAILIMF_ERROR_PARSE) {
332 /* do nothing */
333 }
334 else {
335 res = r;
336 goto err;
337 }
338
339 r = mailimf_token_case_insensitive_parse(message, length, &cur_token, "=?");
340 if (r != MAILIMF_NO_ERROR) {
341 res = r;
342 goto err;
343 }
344
345 r = mailmime_charset_parse(message, length, &cur_token, &charset);
346 if (r != MAILIMF_NO_ERROR) {
347 res = r;
348 goto err;
349 }
350
351 r = mailimf_char_parse(message, length, &cur_token, '?');
352 if (r != MAILIMF_NO_ERROR) {
353 res = r;
354 goto free_charset;
355 }
356
357 r = mailmime_encoding_parse(message, length, &cur_token, &encoding);
358 if (r != MAILIMF_NO_ERROR) {
359 res = r;
360 goto free_charset;
361 }
362
363 r = mailimf_char_parse(message, length, &cur_token, '?');
364 if (r != MAILIMF_NO_ERROR) {
365 res = r;
366 goto free_charset;
367 }
368
369 end = FALSE;
370 end_encoding = cur_token;
371 while (1) {
372 if (end_encoding >= length)
373 break;
374
375 switch (message[end_encoding]) {
376 case '?':
377#if 0
378 case ' ':
379#endif
380 end = TRUE;
381 break;
382 }
383
384 if (end)
385 break;
386
387 end_encoding ++;
388 }
389
390 decoded_len = 0;
391 decoded = NULL;
392 switch (encoding) {
393 case MAILMIME_ENCODING_B:
394 r = mailmime_base64_body_parse(message, end_encoding,
395 &cur_token, &decoded,
396 &decoded_len);
397
398 if (r != MAILIMF_NO_ERROR) {
399 res = r;
400 goto free_charset;
401 }
402 break;
403 case MAILMIME_ENCODING_Q:
404 r = mailmime_quoted_printable_body_parse(message, end_encoding,
405 &cur_token, &decoded,
406 &decoded_len, TRUE);
407
408 if (r != MAILIMF_NO_ERROR) {
409 res = r;
410 goto free_charset;
411 }
412
413 break;
414 }
415
416 text = malloc(decoded_len + 1);
417 if (text == NULL) {
418 res = MAILIMF_ERROR_MEMORY;
419 goto free_charset;
420 }
421
422 if (decoded_len > 0)
423 memcpy(text, decoded, decoded_len);
424 text[decoded_len] = '\0';
425
426 mailmime_decoded_part_free(decoded);
427
428 r = mailimf_token_case_insensitive_parse(message, length, &cur_token, "?=");
429 if (r != MAILIMF_NO_ERROR) {
430 res = r;
431 goto free_encoded_text;
432 }
433
434 if (opening_quote) {
435 r = mailimf_char_parse(message, length, &cur_token, '\"');
436 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
437 res = r;
438 goto free_encoded_text;
439 }
440 }
441
442 ew = mailmime_encoded_word_new(charset, text);
443 if (ew == NULL) {
444 res = MAILIMF_ERROR_MEMORY;
445 goto free_encoded_text;
446 }
447
448 * result = ew;
449 * index = cur_token;
450
451 return MAILIMF_NO_ERROR;
452
453 free_encoded_text:
454 mailmime_encoded_text_free(text);
455 free_charset:
456 mailmime_charset_free(charset);
457 err:
458 return res;
459}
460
461static int mailmime_charset_parse(const char * message, size_t length,
462 size_t * index, char ** charset)
463{
464 return mailmime_etoken_parse(message, length, index, charset);
465}
466
467static int mailmime_encoding_parse(const char * message, size_t length,
468 size_t * index, int * result)
469{
470 size_t cur_token;
471 int encoding;
472
473 cur_token = * index;
474
475 if (cur_token >= length)
476 return MAILIMF_ERROR_PARSE;
477
478 switch ((char) toupper((unsigned char) message[cur_token])) {
479 case 'Q':
480 encoding = MAILMIME_ENCODING_Q;
481 break;
482 case 'B':
483 encoding = MAILMIME_ENCODING_B;
484 break;
485 default:
486 return MAILIMF_ERROR_INVAL;
487 }
488
489 cur_token ++;
490
491 * result = encoding;
492 * index = cur_token;
493
494 return MAILIMF_NO_ERROR;
495}
496
497int is_etoken_char(char ch)
498{
499 unsigned char uch = ch;
500
501 if (uch < 31)
502 return FALSE;
503
504 switch (uch) {
505 case ' ':
506 case '(':
507 case ')':
508 case '<':
509 case '>':
510 case '@':
511 case ',':
512 case ';':
513 case ':':
514 case '"':
515 case '/':
516 case '[':
517 case ']':
518 case '?':
519 case '.':
520 case '=':
521 return FALSE;
522 }
523
524 return TRUE;
525}
526
527static int mailmime_etoken_parse(const char * message, size_t length,
528 size_t * index, char ** result)
529{
530 return mailimf_custom_string_parse(message, length,
531 index, result,
532 is_etoken_char);
533}
diff --git a/kmicromail/libetpan/mime/mailmime_decode.h b/kmicromail/libetpan/mime/mailmime_decode.h
new file mode 100644
index 0000000..034db6f
--- a/dev/null
+++ b/kmicromail/libetpan/mime/mailmime_decode.h
@@ -0,0 +1,55 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMIME_DECODE_H
37
38#define MAILMIME_DECODE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailmime_types.h>
45
46int mailmime_encoded_phrase_parse(const char * default_fromcode,
47 const char * message, size_t length,
48 size_t * index, const char * tocode,
49 char ** result);
50
51#ifdef __cplusplus
52}
53#endif
54
55#endif
diff --git a/kmicromail/libetpan/mime/mailmime_disposition.c b/kmicromail/libetpan/mime/mailmime_disposition.c
new file mode 100644
index 0000000..9d8dfec
--- a/dev/null
+++ b/kmicromail/libetpan/mime/mailmime_disposition.c
@@ -0,0 +1,595 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailmime_disposition.h"
37#include "mailmime.h"
38
39#include <ctype.h>
40#include <stdlib.h>
41
42static int
43mailmime_disposition_parm_parse(const char * message, size_t length,
44 size_t * index,
45 struct mailmime_disposition_parm **
46 result);
47
48static int
49mailmime_creation_date_parm_parse(const char * message, size_t length,
50 size_t * index, char ** result);
51
52static int
53mailmime_filename_parm_parse(const char * message, size_t length,
54 size_t * index, char ** result);
55
56static int
57mailmime_modification_date_parm_parse(const char * message, size_t length,
58 size_t * index, char ** result);
59
60static int
61mailmime_read_date_parm_parse(const char * message, size_t length,
62 size_t * index, char ** result);
63
64static int
65mailmime_size_parm_parse(const char * message, size_t length,
66 size_t * index, size_t * result);
67
68static int
69mailmime_quoted_date_time_parse(const char * message, size_t length,
70 size_t * index, char ** result);
71
72/*
73 disposition := "Content-Disposition" ":"
74 disposition-type
75 *(";" disposition-parm)
76
77*/
78
79
80int mailmime_disposition_parse(const char * message, size_t length,
81 size_t * index,
82 struct mailmime_disposition ** result)
83{
84 size_t final_token;
85 size_t cur_token;
86 struct mailmime_disposition_type * dsp_type;
87 clist * list;
88 struct mailmime_disposition * dsp;
89 int r;
90 int res;
91
92 cur_token = * index;
93
94 r = mailmime_disposition_type_parse(message, length, &cur_token,
95 &dsp_type);
96 if (r != MAILIMF_NO_ERROR) {
97 res = r;
98 goto err;
99 }
100
101 list = clist_new();
102 if (list == NULL) {
103 res = MAILIMF_ERROR_MEMORY;
104 goto free_type;
105 }
106
107 while (1) {
108 struct mailmime_disposition_parm * param;
109
110 final_token = cur_token;
111 r = mailimf_unstrict_char_parse(message, length, &cur_token, ';');
112 if (r == MAILIMF_NO_ERROR) {
113 /* do nothing */
114 }
115 else if (r == MAILIMF_ERROR_PARSE) {
116 break;
117 }
118 else {
119 res = r;
120 goto free_list;
121 }
122
123 r = mailmime_disposition_parm_parse(message, length, &cur_token, &param);
124 if (r == MAILIMF_NO_ERROR) {
125 /* do nothing */
126 }
127 else if (r == MAILIMF_ERROR_PARSE) {
128 cur_token = final_token;
129 break;
130 }
131 else {
132 res = r;
133 goto free_list;
134 }
135
136 r = clist_append(list, param);
137 if (r < 0) {
138 res = MAILIMF_ERROR_MEMORY;
139 goto free_list;
140 }
141 }
142
143 dsp = mailmime_disposition_new(dsp_type, list);
144 if (dsp == NULL) {
145 res = MAILIMF_ERROR_MEMORY;
146 goto free_list;
147 }
148
149 * result = dsp;
150 * index = cur_token;
151
152 return MAILIMF_NO_ERROR;
153
154 free_list:
155 clist_foreach(list, (clist_func) mailmime_disposition_parm_free, NULL);
156 clist_free(list);
157 free_type:
158 mailmime_disposition_type_free(dsp_type);
159 err:
160 return res;
161}
162
163 /*
164 disposition-type := "inline"
165 / "attachment"
166 / extension-token
167 ; values are not case-sensitive
168
169*/
170
171
172
173int
174mailmime_disposition_type_parse(const char * message, size_t length,
175 size_t * index,
176 struct mailmime_disposition_type ** result)
177{
178 size_t cur_token;
179 int type;
180 char * extension;
181 struct mailmime_disposition_type * dsp_type;
182 int r;
183 int res;
184
185 cur_token = * index;
186
187 r = mailimf_cfws_parse(message, length, &cur_token);
188 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
189 res = r;
190 goto err;
191 }
192
193 type = MAILMIME_DISPOSITION_TYPE_ERROR; /* XXX - removes a gcc warning */
194
195 extension = NULL;
196 r = mailimf_token_case_insensitive_parse(message, length,
197 &cur_token, "inline");
198 if (r == MAILIMF_NO_ERROR)
199 type = MAILMIME_DISPOSITION_TYPE_INLINE;
200
201 if (r == MAILIMF_ERROR_PARSE) {
202 r = mailimf_token_case_insensitive_parse(message, length,
203 &cur_token, "attachment");
204 if (r == MAILIMF_NO_ERROR)
205 type = MAILMIME_DISPOSITION_TYPE_ATTACHMENT;
206 }
207
208 if (r == MAILIMF_ERROR_PARSE) {
209 r = mailmime_extension_token_parse(message, length, &cur_token,
210 &extension);
211 if (r == MAILIMF_NO_ERROR)
212 type = MAILMIME_DISPOSITION_TYPE_EXTENSION;
213 }
214
215 if (r != MAILIMF_NO_ERROR) {
216 res = r;
217 goto err;
218 }
219
220 dsp_type = mailmime_disposition_type_new(type, extension);
221 if (dsp_type == NULL) {
222 res = MAILIMF_ERROR_MEMORY;
223 goto free;
224 }
225
226 * result = dsp_type;
227 * index = cur_token;
228
229 return MAILIMF_NO_ERROR;
230
231 free:
232 if (extension != NULL)
233 free(extension);
234 err:
235 return res;
236}
237
238/*
239 disposition-parm := filename-parm
240 / creation-date-parm
241 / modification-date-parm
242 / read-date-parm
243 / size-parm
244 / parameter
245*/
246
247
248int mailmime_disposition_guess_type(const char * message, size_t length,
249 size_t index)
250{
251 if (index >= length)
252 return MAILMIME_DISPOSITION_PARM_PARAMETER;
253
254 switch ((char) toupper((unsigned char) message[index])) {
255 case 'F':
256 return MAILMIME_DISPOSITION_PARM_FILENAME;
257 case 'C':
258 return MAILMIME_DISPOSITION_PARM_CREATION_DATE;
259 case 'M':
260 return MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE;
261 case 'R':
262 return MAILMIME_DISPOSITION_PARM_READ_DATE;
263 case 'S':
264 return MAILMIME_DISPOSITION_PARM_SIZE;
265 default:
266 return MAILMIME_DISPOSITION_PARM_PARAMETER;
267 }
268}
269
270static int
271mailmime_disposition_parm_parse(const char * message, size_t length,
272 size_t * index,
273 struct mailmime_disposition_parm **
274 result)
275{
276 char * filename;
277 char * creation_date;
278 char * modification_date;
279 char * read_date;
280 size_t size;
281 struct mailmime_parameter * parameter;
282 size_t cur_token;
283 struct mailmime_disposition_parm * dsp_parm;
284 int type;
285 int guessed_type;
286 int r;
287 int res;
288
289 cur_token = * index;
290
291 filename = NULL;
292 creation_date = NULL;
293 modification_date = NULL;
294 read_date = NULL;
295 size = 0;
296 parameter = NULL;
297
298 r = mailimf_cfws_parse(message, length, &cur_token);
299 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
300 res = r;
301 goto err;
302 }
303
304 guessed_type = mailmime_disposition_guess_type(message, length, cur_token);
305
306 type = MAILMIME_DISPOSITION_PARM_PARAMETER;
307
308 switch (guessed_type) {
309 case MAILMIME_DISPOSITION_PARM_FILENAME:
310 r = mailmime_filename_parm_parse(message, length, &cur_token,
311 &filename);
312 if (r == MAILIMF_NO_ERROR)
313 type = guessed_type;
314 else if (r == MAILIMF_ERROR_PARSE) {
315 /* do nothing */
316 }
317 else {
318 res = r;
319 goto err;
320 }
321 break;
322
323 case MAILMIME_DISPOSITION_PARM_CREATION_DATE:
324 r = mailmime_creation_date_parm_parse(message, length, &cur_token,
325 &creation_date);
326 if (r == MAILIMF_NO_ERROR)
327 type = guessed_type;
328 else if (r == MAILIMF_ERROR_PARSE) {
329 /* do nothing */
330 }
331 else {
332 res = r;
333 goto err;
334 }
335 break;
336
337 case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE:
338 r = mailmime_modification_date_parm_parse(message, length, &cur_token,
339 &modification_date);
340 if (r == MAILIMF_NO_ERROR)
341 type = guessed_type;
342 else if (r == MAILIMF_ERROR_PARSE) {
343 /* do nothing */
344 }
345 else {
346 res = r;
347 goto err;
348 }
349 break;
350
351 case MAILMIME_DISPOSITION_PARM_READ_DATE:
352 r = mailmime_read_date_parm_parse(message, length, &cur_token,
353 &read_date);
354 if (r == MAILIMF_NO_ERROR)
355 type = guessed_type;
356 else if (r == MAILIMF_ERROR_PARSE) {
357 /* do nothing */
358 }
359 else {
360 res = r;
361 goto err;
362 }
363 break;
364
365 case MAILMIME_DISPOSITION_PARM_SIZE:
366 r = mailmime_size_parm_parse(message, length, &cur_token,
367 &size);
368 if (r == MAILIMF_NO_ERROR)
369 type = guessed_type;
370 else if (r == MAILIMF_ERROR_PARSE) {
371 /* do nothing */
372 }
373 else {
374 res = r;
375 goto err;
376 }
377 break;
378 }
379
380 if (type == MAILMIME_DISPOSITION_PARM_PARAMETER) {
381 r = mailmime_parameter_parse(message, length, &cur_token,
382 &parameter);
383 if (r != MAILIMF_NO_ERROR) {
384 type = guessed_type;
385 res = r;
386 goto err;
387 }
388 }
389
390 dsp_parm = mailmime_disposition_parm_new(type, filename, creation_date,
391 modification_date, read_date,
392 size, parameter);
393
394 if (dsp_parm == NULL) {
395 res = MAILIMF_ERROR_MEMORY;
396 goto free;
397 }
398
399 * result = dsp_parm;
400 * index = cur_token;
401
402 return MAILIMF_NO_ERROR;
403
404 free:
405 if (filename != NULL)
406 mailmime_filename_parm_free(dsp_parm->pa_data.pa_filename);
407 if (creation_date != NULL)
408 mailmime_creation_date_parm_free(dsp_parm->pa_data.pa_creation_date);
409 if (modification_date != NULL)
410 mailmime_modification_date_parm_free(dsp_parm->pa_data.pa_modification_date);
411 if (read_date != NULL)
412 mailmime_read_date_parm_free(dsp_parm->pa_data.pa_read_date);
413 if (parameter != NULL)
414 mailmime_parameter_free(dsp_parm->pa_data.pa_parameter);
415 err:
416 return res;
417}
418
419/*
420 filename-parm := "filename" "=" value
421*/
422
423static int
424mailmime_filename_parm_parse(const char * message, size_t length,
425 size_t * index, char ** result)
426{
427 char * value;
428 int r;
429 size_t cur_token;
430
431 cur_token = * index;
432
433 r = mailimf_token_case_insensitive_parse(message, length,
434 &cur_token, "filename");
435 if (r != MAILIMF_NO_ERROR)
436 return r;
437
438 r = mailimf_unstrict_char_parse(message, length, &cur_token, '=');
439 if (r != MAILIMF_NO_ERROR)
440 return r;
441
442 r = mailmime_value_parse(message, length, &cur_token, &value);
443 if (r != MAILIMF_NO_ERROR)
444 return r;
445
446 * index = cur_token;
447 * result = value;
448
449 return MAILIMF_NO_ERROR;
450}
451
452/*
453 creation-date-parm := "creation-date" "=" quoted-date-time
454*/
455
456static int
457mailmime_creation_date_parm_parse(const char * message, size_t length,
458 size_t * index, char ** result)
459{
460 char * value;
461 int r;
462 size_t cur_token;
463
464 cur_token = * index;
465
466 r = mailimf_token_case_insensitive_parse(message, length,
467 &cur_token, "creation-date");
468 if (r != MAILIMF_NO_ERROR)
469 return r;
470
471 r = mailimf_unstrict_char_parse(message, length, &cur_token, '=');
472 if (r != MAILIMF_NO_ERROR)
473 return r;
474
475 r = mailmime_quoted_date_time_parse(message, length, &cur_token, &value);
476 if (r != MAILIMF_NO_ERROR)
477 return r;
478
479 * index = cur_token;
480 * result = value;
481
482 return MAILIMF_NO_ERROR;
483}
484
485/*
486 modification-date-parm := "modification-date" "=" quoted-date-time
487*/
488
489static int
490mailmime_modification_date_parm_parse(const char * message, size_t length,
491 size_t * index, char ** result)
492{
493 char * value;
494 size_t cur_token;
495 int r;
496
497 cur_token = * index;
498
499 r = mailimf_token_case_insensitive_parse(message, length,
500 &cur_token, "modification-date");
501 if (r != MAILIMF_NO_ERROR)
502 return r;
503
504 r = mailimf_unstrict_char_parse(message, length, &cur_token, '=');
505 if (r != MAILIMF_NO_ERROR)
506 return r;
507
508 r = mailmime_quoted_date_time_parse(message, length, &cur_token, &value);
509 if (r != MAILIMF_NO_ERROR)
510 return r;
511
512 * index = cur_token;
513 * result = value;
514
515 return MAILIMF_NO_ERROR;
516}
517
518/*
519 read-date-parm := "read-date" "=" quoted-date-time
520*/
521
522static int
523mailmime_read_date_parm_parse(const char * message, size_t length,
524 size_t * index, char ** result)
525{
526 char * value;
527 size_t cur_token;
528 int r;
529
530 cur_token = * index;
531
532 r = mailimf_token_case_insensitive_parse(message, length,
533 &cur_token, "read-date");
534 if (r != MAILIMF_NO_ERROR)
535 return r;
536
537 r = mailimf_unstrict_char_parse(message, length, &cur_token, '=');
538 if (r != MAILIMF_NO_ERROR)
539 return r;
540
541 r = mailmime_quoted_date_time_parse(message, length, &cur_token, &value);
542 if (r != MAILIMF_NO_ERROR)
543 return r;
544
545 * index = cur_token;
546 * result = value;
547
548 return MAILIMF_NO_ERROR;
549}
550
551/*
552 size-parm := "size" "=" 1*DIGIT
553*/
554
555static int
556mailmime_size_parm_parse(const char * message, size_t length,
557 size_t * index, size_t * result)
558{
559 uint32_t value;
560 size_t cur_token;
561 int r;
562
563 cur_token = * index;
564
565 r = mailimf_token_case_insensitive_parse(message, length,
566 &cur_token, "size");
567 if (r != MAILIMF_NO_ERROR)
568 return r;
569
570 r = mailimf_unstrict_char_parse(message, length, &cur_token, '=');
571 if (r != MAILIMF_NO_ERROR)
572 return r;
573
574 r = mailimf_number_parse(message, length, &cur_token, &value);
575 if (r != MAILIMF_NO_ERROR)
576 return r;
577
578 * index = cur_token;
579 * result = value;
580
581 return MAILIMF_NO_ERROR;
582}
583
584/*
585 quoted-date-time := quoted-string
586 ; contents MUST be an RFC 822 `date-time'
587 ; numeric timezones (+HHMM or -HHMM) MUST be used
588*/
589
590static int
591mailmime_quoted_date_time_parse(const char * message, size_t length,
592 size_t * index, char ** result)
593{
594 return mailimf_quoted_string_parse(message, length, index, result);
595}
diff --git a/kmicromail/libetpan/mime/mailmime_disposition.h b/kmicromail/libetpan/mime/mailmime_disposition.h
new file mode 100644
index 0000000..e3bba15
--- a/dev/null
+++ b/kmicromail/libetpan/mime/mailmime_disposition.h
@@ -0,0 +1,62 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMIME_DISPOSITION_H
37
38#define MAILMIME_DISPOSITION_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailmime_types.h>
45
46int mailmime_disposition_parse(const char * message, size_t length,
47 size_t * index,
48 struct mailmime_disposition ** result);
49
50int
51mailmime_disposition_type_parse(const char * message, size_t length,
52 size_t * index,
53 struct mailmime_disposition_type ** result);
54
55int mailmime_disposition_guess_type(const char * message, size_t length,
56 size_t index);
57
58#ifdef __cplusplus
59}
60#endif
61
62#endif
diff --git a/kmicromail/libetpan/mime/mailmime_types.c b/kmicromail/libetpan/mime/mailmime_types.c
new file mode 100644
index 0000000..a81c87a
--- a/dev/null
+++ b/kmicromail/libetpan/mime/mailmime_types.c
@@ -0,0 +1,750 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailmime_types.h"
37#include "mmapstring.h"
38
39#include <string.h>
40#include <stdlib.h>
41
42void mailmime_attribute_free(char * attribute)
43{
44 mailmime_token_free(attribute);
45}
46
47
48
49struct mailmime_composite_type *
50mailmime_composite_type_new(int ct_type, char * ct_token)
51{
52 struct mailmime_composite_type * ct;
53
54 ct = malloc(sizeof(* ct));
55 if (ct == NULL)
56 return NULL;
57
58 ct->ct_type = ct_type;
59 ct->ct_token = ct_token;
60
61 return ct;
62}
63
64void mailmime_composite_type_free(struct mailmime_composite_type * ct)
65{
66 if (ct->ct_token != NULL)
67 mailmime_extension_token_free(ct->ct_token);
68 free(ct);
69}
70
71
72struct mailmime_content *
73mailmime_content_new(struct mailmime_type * ct_type,
74 char * ct_subtype,
75 clist * ct_parameters)
76{
77 struct mailmime_content * content;
78
79 content = malloc(sizeof(* content));
80 if (content == NULL)
81 return NULL;
82
83 content->ct_type = ct_type;
84 content->ct_subtype = ct_subtype;
85 content->ct_parameters = ct_parameters;
86
87 return content;
88}
89
90void mailmime_content_free(struct mailmime_content * content)
91{
92 mailmime_type_free(content->ct_type);
93 mailmime_subtype_free(content->ct_subtype);
94 if (content->ct_parameters != NULL) {
95 clist_foreach(content->ct_parameters,
96 (clist_func) mailmime_parameter_free, NULL);
97 clist_free(content->ct_parameters);
98 }
99
100 free(content);
101}
102
103
104void mailmime_description_free(char * description)
105{
106 free(description);
107}
108
109struct mailmime_discrete_type *
110mailmime_discrete_type_new(int dt_type, char * dt_extension)
111{
112 struct mailmime_discrete_type * discrete_type;
113
114 discrete_type = malloc(sizeof(* discrete_type));
115 if (discrete_type == NULL)
116 return NULL;
117
118 discrete_type->dt_type = dt_type;
119 discrete_type->dt_extension = dt_extension;
120
121 return discrete_type;
122}
123
124void mailmime_discrete_type_free(struct mailmime_discrete_type * discrete_type)
125{
126 if (discrete_type->dt_extension != NULL)
127 mailmime_extension_token_free(discrete_type->dt_extension);
128 free(discrete_type);
129}
130
131void mailmime_encoding_free(struct mailmime_mechanism * encoding)
132{
133 mailmime_mechanism_free(encoding);
134}
135
136void mailmime_extension_token_free(char * extension)
137{
138 mailmime_token_free(extension);
139}
140
141void mailmime_id_free(char * id)
142{
143 mailimf_msg_id_free(id);
144}
145
146struct mailmime_mechanism * mailmime_mechanism_new(int enc_type, char * enc_token)
147{
148 struct mailmime_mechanism * mechanism;
149
150 mechanism = malloc(sizeof(* mechanism));
151 if (mechanism == NULL)
152 return NULL;
153
154 mechanism->enc_type = enc_type;
155 mechanism->enc_token = enc_token;
156
157 return mechanism;
158}
159
160void mailmime_mechanism_free(struct mailmime_mechanism * mechanism)
161{
162 if (mechanism->enc_token != NULL)
163 mailmime_token_free(mechanism->enc_token);
164 free(mechanism);
165}
166
167struct mailmime_parameter *
168mailmime_parameter_new(char * pa_name, char * pa_value)
169{
170 struct mailmime_parameter * parameter;
171
172 parameter = malloc(sizeof(* parameter));
173 if (parameter == NULL)
174 return NULL;
175
176 parameter->pa_name = pa_name;
177 parameter->pa_value = pa_value;
178
179 return parameter;
180}
181
182void mailmime_parameter_free(struct mailmime_parameter * parameter)
183{
184 mailmime_attribute_free(parameter->pa_name);
185 mailmime_value_free(parameter->pa_value);
186 free(parameter);
187}
188
189
190void mailmime_subtype_free(char * subtype)
191{
192 mailmime_extension_token_free(subtype);
193}
194
195
196void mailmime_token_free(char * token)
197{
198 free(token);
199}
200
201
202struct mailmime_type *
203mailmime_type_new(int tp_type,
204 struct mailmime_discrete_type * tp_discrete_type,
205 struct mailmime_composite_type * tp_composite_type)
206{
207 struct mailmime_type * mime_type;
208
209 mime_type = malloc(sizeof(* mime_type));
210 if (mime_type == NULL)
211 return NULL;
212
213 mime_type->tp_type = tp_type;
214 switch (tp_type) {
215 case MAILMIME_TYPE_DISCRETE_TYPE:
216 mime_type->tp_data.tp_discrete_type = tp_discrete_type;
217 break;
218 case MAILMIME_TYPE_COMPOSITE_TYPE:
219 mime_type->tp_data.tp_composite_type = tp_composite_type;
220 break;
221 }
222
223 return mime_type;
224}
225
226void mailmime_type_free(struct mailmime_type * type)
227{
228 switch (type->tp_type) {
229 case MAILMIME_TYPE_DISCRETE_TYPE:
230 mailmime_discrete_type_free(type->tp_data.tp_discrete_type);
231 break;
232 case MAILMIME_TYPE_COMPOSITE_TYPE:
233 mailmime_composite_type_free(type->tp_data.tp_composite_type);
234 break;
235 }
236 free(type);
237}
238
239void mailmime_value_free(char * value)
240{
241 free(value);
242}
243
244
245/*
246void mailmime_x_token_free(gchar * x_token)
247{
248 g_free(x_token);
249}
250*/
251
252struct mailmime_field *
253mailmime_field_new(int fld_type,
254 struct mailmime_content * fld_content,
255 struct mailmime_mechanism * fld_encoding,
256 char * fld_id,
257 char * fld_description,
258 uint32_t fld_version,
259 struct mailmime_disposition * fld_disposition,
260 struct mailmime_language * fld_language)
261{
262 struct mailmime_field * field;
263
264 field = malloc(sizeof(* field));
265 if (field == NULL)
266 return NULL;
267 field->fld_type = fld_type;
268
269 switch (fld_type) {
270 case MAILMIME_FIELD_TYPE:
271 field->fld_data.fld_content = fld_content;
272 break;
273 case MAILMIME_FIELD_TRANSFER_ENCODING:
274 field->fld_data.fld_encoding = fld_encoding;
275 break;
276 case MAILMIME_FIELD_ID:
277 field->fld_data.fld_id = fld_id;
278 break;
279 case MAILMIME_FIELD_DESCRIPTION:
280 field->fld_data.fld_description = fld_description;
281 break;
282 case MAILMIME_FIELD_VERSION:
283 field->fld_data.fld_version = fld_version;
284 break;
285 case MAILMIME_FIELD_DISPOSITION:
286 field->fld_data.fld_disposition = fld_disposition;
287 break;
288 case MAILMIME_FIELD_LANGUAGE:
289 field->fld_data.fld_language = fld_language;
290 break;
291 }
292 return field;
293}
294
295void mailmime_field_free(struct mailmime_field * field)
296{
297 switch (field->fld_type) {
298 case MAILMIME_FIELD_TYPE:
299 if (field->fld_data.fld_content != NULL)
300 mailmime_content_free(field->fld_data.fld_content);
301 break;
302 case MAILMIME_FIELD_TRANSFER_ENCODING:
303 if (field->fld_data.fld_encoding != NULL)
304 mailmime_encoding_free(field->fld_data.fld_encoding);
305 break;
306 case MAILMIME_FIELD_ID:
307 if (field->fld_data.fld_id != NULL)
308 mailmime_id_free(field->fld_data.fld_id);
309 break;
310 case MAILMIME_FIELD_DESCRIPTION:
311 if (field->fld_data.fld_description != NULL)
312 mailmime_description_free(field->fld_data.fld_description);
313 break;
314 case MAILMIME_FIELD_DISPOSITION:
315 if (field->fld_data.fld_disposition != NULL)
316 mailmime_disposition_free(field->fld_data.fld_disposition);
317 break;
318 case MAILMIME_FIELD_LANGUAGE:
319 if (field->fld_data.fld_language != NULL)
320 mailmime_language_free(field->fld_data.fld_language);
321 break;
322 }
323
324 free(field);
325}
326
327struct mailmime_fields * mailmime_fields_new(clist * fld_list)
328{
329 struct mailmime_fields * fields;
330
331 fields = malloc(sizeof(* fields));
332 if (fields == NULL)
333 return NULL;
334
335 fields->fld_list = fld_list;
336
337 return fields;
338}
339
340void mailmime_fields_free(struct mailmime_fields * fields)
341{
342 clist_foreach(fields->fld_list, (clist_func) mailmime_field_free, NULL);
343 clist_free(fields->fld_list);
344 free(fields);
345}
346
347
348/*
349struct mailmime_body_part *
350mailmime_body_part_new(gchar * text, guint32 size)
351{
352 struct mailmime_body_part * body_part;
353
354 body_part = g_new(struct mailmime_body_part, 1);
355 if (body_part == NULL)
356 return NULL;
357
358 body_part->text = text;
359 body_part->size = size;
360
361 return body_part;
362}
363
364void mailmime_body_part_free(struct mailmime_body_part * body_part)
365{
366 g_free(body_part);
367}
368*/
369
370struct mailmime_multipart_body *
371mailmime_multipart_body_new(clist * bd_list)
372{
373 struct mailmime_multipart_body * mp_body;
374
375 mp_body = malloc(sizeof(* mp_body));
376 if (mp_body == NULL)
377 return NULL;
378
379 mp_body->bd_list = bd_list;
380
381 return mp_body;
382}
383
384void mailmime_multipart_body_free(struct mailmime_multipart_body * mp_body)
385{
386 clist_foreach(mp_body->bd_list, (clist_func) mailimf_body_free, NULL);
387 clist_free(mp_body->bd_list);
388 free(mp_body);
389}
390
391
392
393
394struct mailmime * mailmime_new(int mm_type,
395 const char * mm_mime_start, size_t mm_length,
396 struct mailmime_fields * mm_mime_fields,
397 struct mailmime_content * mm_content_type,
398 struct mailmime_data * mm_body,
399 struct mailmime_data * mm_preamble,
400 struct mailmime_data * mm_epilogue,
401 clist * mm_mp_list,
402 struct mailimf_fields * mm_fields,
403 struct mailmime * mm_msg_mime)
404{
405 struct mailmime * mime;
406 clistiter * cur;
407
408 mime = malloc(sizeof(* mime));
409 if (mime == NULL)
410 return NULL;
411
412 mime->mm_parent = NULL;
413 mime->mm_parent_type = MAILMIME_NONE;
414 mime->mm_multipart_pos = NULL;
415
416 mime->mm_type = mm_type;
417 mime->mm_mime_start = mm_mime_start;
418 mime->mm_length = mm_length;
419 mime->mm_mime_fields = mm_mime_fields;
420 mime->mm_content_type = mm_content_type;
421
422 mime->mm_body = mm_body;
423
424 switch (mm_type) {
425 case MAILMIME_SINGLE:
426 mime->mm_data.mm_single = mm_body;
427 break;
428
429 case MAILMIME_MULTIPLE:
430 mime->mm_data.mm_multipart.mm_preamble = mm_preamble;
431 mime->mm_data.mm_multipart.mm_epilogue = mm_epilogue;
432 mime->mm_data.mm_multipart.mm_mp_list = mm_mp_list;
433
434 for(cur = clist_begin(mm_mp_list) ; cur != NULL ;
435 cur = clist_next(cur)) {
436 struct mailmime * submime;
437
438 submime = clist_content(cur);
439 submime->mm_parent = mime;
440 submime->mm_parent_type = MAILMIME_MULTIPLE;
441 submime->mm_multipart_pos = cur;
442 }
443 break;
444
445 case MAILMIME_MESSAGE:
446 mime->mm_data.mm_message.mm_fields = mm_fields;
447 mime->mm_data.mm_message.mm_msg_mime = mm_msg_mime;
448 if (mm_msg_mime != NULL) {
449 mm_msg_mime->mm_parent = mime;
450 mm_msg_mime->mm_parent_type = MAILMIME_MESSAGE;
451 }
452 break;
453
454 }
455
456 return mime;
457}
458
459void mailmime_free(struct mailmime * mime)
460{
461 if (mime->mm_body != NULL)
462 mailmime_data_free(mime->mm_body);
463 switch (mime->mm_type) {
464 case MAILMIME_SINGLE:
465 /* do nothing */
466 break;
467
468 case MAILMIME_MULTIPLE:
469 if (mime->mm_data.mm_multipart.mm_preamble != NULL)
470 mailmime_data_free(mime->mm_data.mm_multipart.mm_preamble);
471 if (mime->mm_data.mm_multipart.mm_epilogue != NULL)
472 mailmime_data_free(mime->mm_data.mm_multipart.mm_epilogue);
473 clist_foreach(mime->mm_data.mm_multipart.mm_mp_list,
474 (clist_func) mailmime_free, NULL);
475 clist_free(mime->mm_data.mm_multipart.mm_mp_list);
476 break;
477
478 case MAILMIME_MESSAGE:
479 if (mime->mm_data.mm_message.mm_fields != NULL)
480 mailimf_fields_free(mime->mm_data.mm_message.mm_fields);
481 if (mime->mm_data.mm_message.mm_msg_mime != NULL)
482 mailmime_free(mime->mm_data.mm_message.mm_msg_mime);
483 break;
484
485 }
486 if (mime->mm_mime_fields != NULL)
487 mailmime_fields_free(mime->mm_mime_fields);
488 if (mime->mm_content_type != NULL)
489 mailmime_content_free(mime->mm_content_type);
490 free(mime);
491}
492
493
494
495struct mailmime_encoded_word *
496mailmime_encoded_word_new(char * wd_charset, char * wd_text)
497{
498 struct mailmime_encoded_word * ew;
499
500 ew = malloc(sizeof(* ew));
501 if (ew == NULL)
502 return NULL;
503 ew->wd_charset = wd_charset;
504 ew->wd_text = wd_text;
505
506 return ew;
507}
508
509void mailmime_charset_free(char * charset)
510{
511 free(charset);
512}
513
514void mailmime_encoded_text_free(char * text)
515{
516 free(text);
517}
518
519void mailmime_encoded_word_free(struct mailmime_encoded_word * ew)
520{
521 mailmime_charset_free(ew->wd_charset);
522 mailmime_encoded_text_free(ew->wd_text);
523 free(ew);
524}
525
526
527
528/* mailmime_disposition */
529
530
531struct mailmime_disposition *
532mailmime_disposition_new(struct mailmime_disposition_type * dsp_type,
533 clist * dsp_parms)
534{
535 struct mailmime_disposition * dsp;
536
537 dsp = malloc(sizeof(* dsp));
538 if (dsp == NULL)
539 return NULL;
540 dsp->dsp_type = dsp_type;
541 dsp->dsp_parms = dsp_parms;
542
543 return dsp;
544}
545
546void mailmime_disposition_free(struct mailmime_disposition * dsp)
547{
548 mailmime_disposition_type_free(dsp->dsp_type);
549 clist_foreach(dsp->dsp_parms,
550 (clist_func) mailmime_disposition_parm_free, NULL);
551 clist_free(dsp->dsp_parms);
552 free(dsp);
553}
554
555
556
557struct mailmime_disposition_type *
558mailmime_disposition_type_new(int dsp_type, char * dsp_extension)
559{
560 struct mailmime_disposition_type * m_dsp_type;
561
562 m_dsp_type = malloc(sizeof(* m_dsp_type));
563 if (m_dsp_type == NULL)
564 return NULL;
565
566 m_dsp_type->dsp_type = dsp_type;
567 m_dsp_type->dsp_extension = dsp_extension;
568
569 return m_dsp_type;
570}
571
572void mailmime_disposition_type_free(struct mailmime_disposition_type * dsp_type)
573{
574 if (dsp_type->dsp_extension != NULL)
575 free(dsp_type->dsp_extension);
576 free(dsp_type);
577}
578
579
580struct mailmime_disposition_parm *
581mailmime_disposition_parm_new(int pa_type,
582 char * pa_filename,
583 char * pa_creation_date,
584 char * pa_modification_date,
585 char * pa_read_date,
586 size_t pa_size,
587 struct mailmime_parameter * pa_parameter)
588{
589 struct mailmime_disposition_parm * dsp_parm;
590
591 dsp_parm = malloc(sizeof(* dsp_parm));
592 if (dsp_parm == NULL)
593 return NULL;
594
595 dsp_parm->pa_type = pa_type;
596 switch (pa_type) {
597 case MAILMIME_DISPOSITION_PARM_FILENAME:
598 dsp_parm->pa_data.pa_filename = pa_filename;
599 break;
600 case MAILMIME_DISPOSITION_PARM_CREATION_DATE:
601 dsp_parm->pa_data.pa_creation_date = pa_creation_date;
602 break;
603 case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE:
604 dsp_parm->pa_data.pa_modification_date = pa_modification_date;
605 break;
606 case MAILMIME_DISPOSITION_PARM_READ_DATE:
607 dsp_parm->pa_data.pa_read_date = pa_read_date;
608 break;
609 case MAILMIME_DISPOSITION_PARM_SIZE:
610 dsp_parm->pa_data.pa_size = pa_size;
611 break;
612 case MAILMIME_DISPOSITION_PARM_PARAMETER:
613 dsp_parm->pa_data.pa_parameter = pa_parameter;
614 break;
615 }
616
617 return dsp_parm;
618}
619
620void mailmime_disposition_parm_free(struct mailmime_disposition_parm *
621 dsp_parm)
622{
623 switch (dsp_parm->pa_type) {
624 case MAILMIME_DISPOSITION_PARM_FILENAME:
625 mailmime_filename_parm_free(dsp_parm->pa_data.pa_filename);
626 break;
627 case MAILMIME_DISPOSITION_PARM_CREATION_DATE:
628 mailmime_creation_date_parm_free(dsp_parm->pa_data.pa_creation_date);
629 break;
630 case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE:
631 mailmime_modification_date_parm_free(dsp_parm->pa_data.pa_modification_date);
632 break;
633 case MAILMIME_DISPOSITION_PARM_READ_DATE:
634 mailmime_read_date_parm_free(dsp_parm->pa_data.pa_read_date);
635 break;
636 case MAILMIME_DISPOSITION_PARM_PARAMETER:
637 mailmime_parameter_free(dsp_parm->pa_data.pa_parameter);
638 break;
639 }
640
641 free(dsp_parm);
642}
643
644
645void mailmime_filename_parm_free(char * filename)
646{
647 mailmime_value_free(filename);
648}
649
650void mailmime_creation_date_parm_free(char * date)
651{
652 mailmime_quoted_date_time_free(date);
653}
654
655void mailmime_modification_date_parm_free(char * date)
656{
657 mailmime_quoted_date_time_free(date);
658}
659
660void mailmime_read_date_parm_free(char * date)
661{
662 mailmime_quoted_date_time_free(date);
663}
664
665void mailmime_quoted_date_time_free(char * date)
666{
667 mailimf_quoted_string_free(date);
668}
669
670struct mailmime_section * mailmime_section_new(clist * sec_list)
671{
672 struct mailmime_section * section;
673
674 section = malloc(sizeof(* section));
675 if (section == NULL)
676 return NULL;
677
678 section->sec_list = sec_list;
679
680 return section;
681}
682
683void mailmime_section_free(struct mailmime_section * section)
684{
685 clist_foreach(section->sec_list, (clist_func) free, NULL);
686 clist_free(section->sec_list);
687 free(section);
688}
689
690
691
692struct mailmime_language * mailmime_language_new(clist * lg_list)
693{
694 struct mailmime_language * lang;
695
696 lang = malloc(sizeof(* lang));
697 if (lang == NULL)
698 return NULL;
699
700 lang->lg_list = lg_list;
701
702 return lang;
703}
704
705void mailmime_language_free(struct mailmime_language * lang)
706{
707 clist_foreach(lang->lg_list, (clist_func) mailimf_atom_free, NULL);
708 clist_free(lang->lg_list);
709 free(lang);
710}
711
712void mailmime_decoded_part_free(char * part)
713{
714 mmap_string_unref(part);
715}
716
717struct mailmime_data * mailmime_data_new(int dt_type, int dt_encoding,
718 int dt_encoded, const char * dt_data, size_t dt_length, char * dt_filename)
719{
720 struct mailmime_data * mime_data;
721
722 mime_data = malloc(sizeof(* mime_data));
723 if (mime_data == NULL)
724 return NULL;
725
726 mime_data->dt_type = dt_type;
727 mime_data->dt_encoding = dt_encoding;
728 mime_data->dt_encoded = dt_encoded;
729 switch (dt_type) {
730 case MAILMIME_DATA_TEXT:
731 mime_data->dt_data.dt_text.dt_data = dt_data;
732 mime_data->dt_data.dt_text.dt_length = dt_length;
733 break;
734 case MAILMIME_DATA_FILE:
735 mime_data->dt_data.dt_filename = dt_filename;
736 break;
737 }
738
739 return mime_data;
740}
741
742void mailmime_data_free(struct mailmime_data * mime_data)
743{
744 switch (mime_data->dt_type) {
745 case MAILMIME_DATA_FILE:
746 free(mime_data->dt_data.dt_filename);
747 break;
748 }
749 free(mime_data);
750}
diff --git a/kmicromail/libetpan/mime/mailmime_types.h b/kmicromail/libetpan/mime/mailmime_types.h
new file mode 100644
index 0000000..3bb3b10
--- a/dev/null
+++ b/kmicromail/libetpan/mime/mailmime_types.h
@@ -0,0 +1,440 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMIME_TYPES_H
37
38#define MAILMIME_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45#include <libetpan/mailimf.h>
46#include <libetpan/clist.h>
47
48enum {
49 MAILMIME_COMPOSITE_TYPE_ERROR,
50 MAILMIME_COMPOSITE_TYPE_MESSAGE,
51 MAILMIME_COMPOSITE_TYPE_MULTIPART,
52 MAILMIME_COMPOSITE_TYPE_EXTENSION
53};
54
55struct mailmime_composite_type {
56 int ct_type;
57 char * ct_token;
58};
59
60
61struct mailmime_content {
62 struct mailmime_type * ct_type;
63 char * ct_subtype;
64 clist * ct_parameters; /* elements are (struct mailmime_parameter *) */
65};
66
67
68enum {
69 MAILMIME_DISCRETE_TYPE_ERROR,
70 MAILMIME_DISCRETE_TYPE_TEXT,
71 MAILMIME_DISCRETE_TYPE_IMAGE,
72 MAILMIME_DISCRETE_TYPE_AUDIO,
73 MAILMIME_DISCRETE_TYPE_VIDEO,
74 MAILMIME_DISCRETE_TYPE_APPLICATION,
75 MAILMIME_DISCRETE_TYPE_EXTENSION
76};
77
78struct mailmime_discrete_type {
79 int dt_type;
80 char * dt_extension;
81};
82
83enum {
84 MAILMIME_FIELD_NONE,
85 MAILMIME_FIELD_TYPE,
86 MAILMIME_FIELD_TRANSFER_ENCODING,
87 MAILMIME_FIELD_ID,
88 MAILMIME_FIELD_DESCRIPTION,
89 MAILMIME_FIELD_VERSION,
90 MAILMIME_FIELD_DISPOSITION,
91 MAILMIME_FIELD_LANGUAGE,
92};
93
94struct mailmime_field {
95 int fld_type;
96 union {
97 struct mailmime_content * fld_content;
98 struct mailmime_mechanism * fld_encoding;
99 char * fld_id;
100 char * fld_description;
101 uint32_t fld_version;
102 struct mailmime_disposition * fld_disposition;
103 struct mailmime_language * fld_language;
104 } fld_data;
105};
106
107enum {
108 MAILMIME_MECHANISM_ERROR,
109 MAILMIME_MECHANISM_7BIT,
110 MAILMIME_MECHANISM_8BIT,
111 MAILMIME_MECHANISM_BINARY,
112 MAILMIME_MECHANISM_QUOTED_PRINTABLE,
113 MAILMIME_MECHANISM_BASE64,
114 MAILMIME_MECHANISM_TOKEN
115};
116
117struct mailmime_mechanism {
118 int enc_type;
119 char * enc_token;
120};
121
122
123struct mailmime_fields {
124 clist * fld_list; /* list of (struct mailmime_field *) */
125};
126
127
128struct mailmime_parameter {
129 char * pa_name;
130 char * pa_value;
131};
132
133enum {
134 MAILMIME_TYPE_ERROR,
135 MAILMIME_TYPE_DISCRETE_TYPE,
136 MAILMIME_TYPE_COMPOSITE_TYPE
137};
138
139struct mailmime_type {
140 int tp_type;
141 union {
142 struct mailmime_discrete_type * tp_discrete_type;
143 struct mailmime_composite_type * tp_composite_type;
144 } tp_data;
145};
146
147void mailmime_attribute_free(char * attribute);
148
149struct mailmime_composite_type *
150mailmime_composite_type_new(int ct_type, char * ct_token);
151
152void mailmime_composite_type_free(struct mailmime_composite_type * ct);
153
154struct mailmime_content *
155mailmime_content_new(struct mailmime_type * ct_type,
156 char * ct_subtype,
157 clist * ct_parameters);
158
159void mailmime_content_free(struct mailmime_content * content);
160
161void mailmime_description_free(char * description);
162
163struct mailmime_discrete_type *
164mailmime_discrete_type_new(int dt_type, char * dt_extension);
165
166void mailmime_discrete_type_free(struct mailmime_discrete_type *
167 discrete_type);
168
169void mailmime_encoding_free(struct mailmime_mechanism * encoding);
170
171void mailmime_extension_token_free(char * extension);
172
173void mailmime_id_free(char * id);
174
175struct mailmime_mechanism * mailmime_mechanism_new(int enc_type, char * enc_token);
176
177void mailmime_mechanism_free(struct mailmime_mechanism * mechanism);
178
179struct mailmime_parameter *
180mailmime_parameter_new(char * pa_name, char * pa_value);
181
182void mailmime_parameter_free(struct mailmime_parameter * parameter);
183
184void mailmime_subtype_free(char * subtype);
185
186void mailmime_token_free(char * token);
187
188struct mailmime_type *
189mailmime_type_new(int tp_type,
190 struct mailmime_discrete_type * tp_discrete_type,
191 struct mailmime_composite_type * tp_composite_type);
192
193void mailmime_type_free(struct mailmime_type * type);
194
195void mailmime_value_free(char * value);
196
197
198
199struct mailmime_language {
200 clist * lg_list; /* atom (char *) */
201};
202
203struct mailmime_language * mailmime_language_new(clist * lg_list);
204
205void mailmime_language_free(struct mailmime_language * lang);
206
207
208/*
209void mailmime_x_token_free(gchar * x_token);
210*/
211
212struct mailmime_field *
213mailmime_field_new(int fld_type,
214 struct mailmime_content * fld_content,
215 struct mailmime_mechanism * fld_encoding,
216 char * fld_id,
217 char * fld_description,
218 uint32_t fld_version,
219 struct mailmime_disposition * fld_disposition,
220 struct mailmime_language * fld_language);
221
222void mailmime_field_free(struct mailmime_field * field);
223
224struct mailmime_fields * mailmime_fields_new(clist * fld_list);
225
226void mailmime_fields_free(struct mailmime_fields * fields);
227
228
229struct mailmime_multipart_body {
230 clist * bd_list;
231};
232
233struct mailmime_multipart_body *
234mailmime_multipart_body_new(clist * bd_list);
235
236void mailmime_multipart_body_free(struct mailmime_multipart_body * mp_body);
237
238
239enum {
240 MAILMIME_DATA_TEXT,
241 MAILMIME_DATA_FILE,
242};
243
244struct mailmime_data {
245 int dt_type;
246 int dt_encoding;
247 int dt_encoded;
248 union {
249 struct {
250 const char * dt_data;
251 size_t dt_length;
252 } dt_text;
253 char * dt_filename;
254 } dt_data;
255};
256
257struct mailmime_data * mailmime_data_new(int dt_type, int dt_encoding,
258 int dt_encoded, const char * dt_data, size_t dt_length,
259 char * dt_filename);
260
261void mailmime_data_free(struct mailmime_data * mime_data);
262
263
264enum {
265 MAILMIME_NONE,
266 MAILMIME_SINGLE,
267 MAILMIME_MULTIPLE,
268 MAILMIME_MESSAGE,
269};
270
271struct mailmime {
272 /* parent information */
273 int mm_parent_type;
274 struct mailmime * mm_parent;
275 clistiter * mm_multipart_pos;
276
277 int mm_type;
278 const char * mm_mime_start;
279 size_t mm_length;
280
281 struct mailmime_fields * mm_mime_fields;
282 struct mailmime_content * mm_content_type;
283
284 struct mailmime_data * mm_body;
285 union {
286 /* single part */
287 struct mailmime_data * mm_single; /* XXX - was body */
288
289 /* multi-part */
290 struct {
291 struct mailmime_data * mm_preamble;
292 struct mailmime_data * mm_epilogue;
293 clist * mm_mp_list;
294 } mm_multipart;
295
296 /* message */
297 struct {
298 struct mailimf_fields * mm_fields;
299 struct mailmime * mm_msg_mime;
300 } mm_message;
301
302 } mm_data;
303};
304
305struct mailmime * mailmime_new(int mm_type,
306 const char * mm_mime_start, size_t mm_length,
307 struct mailmime_fields * mm_mime_fields,
308 struct mailmime_content * mm_content_type,
309 struct mailmime_data * mm_body,
310 struct mailmime_data * mm_preamble,
311 struct mailmime_data * mm_epilogue,
312 clist * mm_mp_list,
313 struct mailimf_fields * mm_fields,
314 struct mailmime * mm_msg_mime);
315
316void mailmime_free(struct mailmime * mime);
317
318struct mailmime_encoded_word {
319 char * wd_charset;
320 char * wd_text;
321};
322
323struct mailmime_encoded_word *
324mailmime_encoded_word_new(char * wd_charset, char * wd_text);
325
326void mailmime_encoded_word_free(struct mailmime_encoded_word * ew);
327
328void mailmime_charset_free(char * charset);
329
330void mailmime_encoded_text_free(char * text);
331
332
333struct mailmime_disposition {
334 struct mailmime_disposition_type * dsp_type;
335 clist * dsp_parms; /* struct mailmime_disposition_parm */
336};
337
338
339enum {
340 MAILMIME_DISPOSITION_TYPE_ERROR,
341 MAILMIME_DISPOSITION_TYPE_INLINE,
342 MAILMIME_DISPOSITION_TYPE_ATTACHMENT,
343 MAILMIME_DISPOSITION_TYPE_EXTENSION
344};
345
346struct mailmime_disposition_type {
347 int dsp_type;
348 char * dsp_extension;
349};
350
351
352enum {
353 MAILMIME_DISPOSITION_PARM_FILENAME,
354 MAILMIME_DISPOSITION_PARM_CREATION_DATE,
355 MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE,
356 MAILMIME_DISPOSITION_PARM_READ_DATE,
357 MAILMIME_DISPOSITION_PARM_SIZE,
358 MAILMIME_DISPOSITION_PARM_PARAMETER
359};
360
361struct mailmime_disposition_parm {
362 int pa_type;
363 union {
364 char * pa_filename;
365 char * pa_creation_date;
366 char * pa_modification_date;
367 char * pa_read_date;
368 size_t pa_size;
369 struct mailmime_parameter * pa_parameter;
370 } pa_data;
371};
372
373struct mailmime_disposition *
374mailmime_disposition_new(struct mailmime_disposition_type * dsp_type,
375 clist * dsp_parms);
376
377void mailmime_disposition_free(struct mailmime_disposition * dsp);
378
379struct mailmime_disposition_type *
380mailmime_disposition_type_new(int dt_type, char * dt_extension);
381
382void mailmime_disposition_type_free(struct mailmime_disposition_type * dsp_type);
383
384struct mailmime_disposition_parm *
385mailmime_disposition_parm_new(int pa_type,
386 char * pa_filename,
387 char * pa_creation_date,
388 char * pa_modification_date,
389 char * pa_read_date,
390 size_t pa_size,
391 struct mailmime_parameter * pa_parameter);
392
393void mailmime_disposition_parm_free(struct mailmime_disposition_parm *
394 dsp_parm);
395
396void mailmime_filename_parm_free(char * filename);
397
398void mailmime_creation_date_parm_free(char * date);
399
400void mailmime_modification_date_parm_free(char * date);
401
402void mailmime_read_date_parm_free(char * date);
403
404void mailmime_quoted_date_time_free(char * date);
405
406struct mailmime_section {
407 clist * sec_list; /* list of (uint32 *) */
408};
409
410struct mailmime_section * mailmime_section_new(clist * list);
411
412void mailmime_section_free(struct mailmime_section * section);
413
414
415void mailmime_decoded_part_free(char * part);
416
417struct mailmime_single_fields {
418 struct mailmime_content * fld_content;
419 char * fld_content_charset;
420 char * fld_content_boundary;
421 char * fld_content_name;
422 struct mailmime_mechanism * fld_encoding;
423 char * fld_id;
424 char * fld_description;
425 uint32_t fld_version;
426 struct mailmime_disposition * fld_disposition;
427 char * fld_disposition_filename;
428 char * fld_disposition_creation_date;
429 char * fld_disposition_modification_date;
430 char * fld_disposition_read_date;
431 size_t fld_disposition_size;
432 struct mailmime_language * fld_language;
433};
434
435#ifdef __cplusplus
436}
437#endif
438
439#endif
440
diff --git a/kmicromail/libetpan/mime/mailmime_types_helper.c b/kmicromail/libetpan/mime/mailmime_types_helper.c
new file mode 100644
index 0000000..83fa1d4
--- a/dev/null
+++ b/kmicromail/libetpan/mime/mailmime_types_helper.c
@@ -0,0 +1,1385 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailmime_types_helper.h"
37#include "clist.h"
38
39#include "mailmime.h"
40
41#include <string.h>
42#include <time.h>
43#include <sys/types.h>
44#include <unistd.h>
45#include <stdlib.h>
46
47#define MIME_VERSION (1 << 16)
48
49int mailmime_transfer_encoding_get(struct mailmime_fields * fields)
50{
51 clistiter * cur;
52
53 for(cur = clist_begin(fields->fld_list) ;
54 cur != NULL ; cur = clist_next(cur)) {
55 struct mailmime_field * field;
56
57 field = clist_content(cur);
58 if (field->fld_type == MAILMIME_FIELD_TRANSFER_ENCODING)
59 return field->fld_data.fld_encoding->enc_type;
60 }
61
62 return MAILMIME_MECHANISM_8BIT;
63}
64
65struct mailmime_disposition *
66mailmime_disposition_new_filename(int type, char * filename)
67{
68 return mailmime_disposition_new_with_data(type, filename,
69 NULL, NULL, NULL, (size_t) -1);
70
71}
72
73struct mailmime_fields * mailmime_fields_new_empty(void)
74{
75 clist * list;
76 struct mailmime_fields * fields;
77
78 list = clist_new();
79 if (list == NULL)
80 goto err;
81
82 fields = mailmime_fields_new(list);
83 if (fields == NULL)
84 goto free;
85
86 return fields;
87
88 free:
89 clist_free(list);
90 err:
91 return NULL;
92}
93
94int mailmime_fields_add(struct mailmime_fields * fields,
95 struct mailmime_field * field)
96{
97 int r;
98
99 r = clist_append(fields->fld_list, field);
100 if (r < 0)
101 return MAILIMF_ERROR_MEMORY;
102
103 return MAILIMF_NO_ERROR;
104}
105
106static void mailmime_field_detach(struct mailmime_field * field)
107{
108 switch (field->fld_type) {
109 case MAILMIME_FIELD_TYPE:
110 field->fld_data.fld_content = NULL;
111 break;
112 case MAILMIME_FIELD_TRANSFER_ENCODING:
113 field->fld_data.fld_encoding = NULL;
114 break;
115 case MAILMIME_FIELD_ID:
116 field->fld_data.fld_id = NULL;
117 break;
118 case MAILMIME_FIELD_DESCRIPTION:
119 field->fld_data.fld_description = NULL;
120 break;
121 case MAILMIME_FIELD_DISPOSITION:
122 field->fld_data.fld_disposition = NULL;
123 break;
124 case MAILMIME_FIELD_LANGUAGE:
125 field->fld_data.fld_language = NULL;
126 break;
127 }
128}
129
130struct mailmime_fields *
131mailmime_fields_new_with_data(struct mailmime_mechanism * encoding,
132 char * id,
133 char * description,
134 struct mailmime_disposition * disposition,
135 struct mailmime_language * language)
136{
137 struct mailmime_field * field;
138 struct mailmime_fields * fields;
139 int r;
140
141 fields = mailmime_fields_new_empty();
142 if (fields == NULL)
143 goto err;
144
145#if 0
146 if (content != NULL) {
147 field = mailmime_field_new(MAILMIME_FIELD_TYPE,
148 content, NULL, NULL, NULL, 0, NULL, NULL);
149 if (field == NULL)
150 goto free;
151
152 r = mailmime_fields_add(fields, field);
153 if (r != MAILIMF_NO_ERROR) {
154 mailmime_field_detach(field);
155 mailmime_field_free(field);
156 goto free;
157 }
158 }
159#endif
160
161 if (encoding != NULL) {
162 field = mailmime_field_new(MAILMIME_FIELD_TRANSFER_ENCODING,
163 NULL, encoding, NULL, NULL, 0, NULL, NULL);
164 if (field == NULL)
165 goto free;
166
167 r = mailmime_fields_add(fields, field);
168 if (r != MAILIMF_NO_ERROR) {
169 mailmime_field_detach(field);
170 mailmime_field_free(field);
171 goto free;
172 }
173 }
174
175 if (id != NULL) {
176 field = mailmime_field_new(MAILMIME_FIELD_ID,
177 NULL, NULL, id, NULL, 0, NULL, NULL);
178 if (field == NULL)
179 goto free;
180
181 r = mailmime_fields_add(fields, field);
182 if (r != MAILIMF_NO_ERROR) {
183 mailmime_field_detach(field);
184 mailmime_field_free(field);
185 goto free;
186 }
187 }
188
189 if (description != NULL) {
190 field = mailmime_field_new(MAILMIME_FIELD_DESCRIPTION,
191 NULL, NULL, NULL, description, 0, NULL, NULL);
192 if (field == NULL)
193 goto free;
194
195 r = mailmime_fields_add(fields, field);
196 if (r != MAILIMF_NO_ERROR) {
197 mailmime_field_detach(field);
198 mailmime_field_free(field);
199 goto free;
200 }
201 }
202
203 if (disposition != NULL) {
204 field = mailmime_field_new(MAILMIME_FIELD_DISPOSITION,
205 NULL, NULL, NULL, NULL, 0, disposition, NULL);
206 if (field == NULL)
207 goto free;
208
209 r = mailmime_fields_add(fields, field);
210 if (r != MAILIMF_NO_ERROR) {
211 mailmime_field_detach(field);
212 mailmime_field_free(field);
213 goto free;
214 }
215 }
216
217 if (language != NULL) {
218 field = mailmime_field_new(MAILMIME_FIELD_DISPOSITION,
219 NULL, NULL, NULL, NULL, 0, NULL, language);
220 if (field == NULL)
221 goto free;
222
223 r = mailmime_fields_add(fields, field);
224 if (r != MAILIMF_NO_ERROR) {
225 mailmime_field_detach(field);
226 mailmime_field_free(field);
227 goto free;
228 }
229 }
230
231 return fields;
232
233 free:
234 clist_foreach(fields->fld_list, (clist_func) mailmime_field_detach, NULL);
235 mailmime_fields_free(fields);
236 err:
237 return NULL;
238}
239
240struct mailmime_fields *
241mailmime_fields_new_with_version(struct mailmime_mechanism * encoding,
242 char * id,
243 char * description,
244 struct mailmime_disposition * disposition,
245 struct mailmime_language * language)
246{
247 struct mailmime_field * field;
248 struct mailmime_fields * fields;
249 int r;
250
251 fields = mailmime_fields_new_with_data(encoding, id, description,
252 disposition, language);
253 if (fields == NULL)
254 goto err;
255
256 field = mailmime_field_new(MAILMIME_FIELD_VERSION,
257 NULL, NULL, NULL, NULL, MIME_VERSION, NULL, NULL);
258 if (field == NULL)
259 goto free;
260
261 r = mailmime_fields_add(fields, field);
262 if (r != MAILIMF_NO_ERROR) {
263 mailmime_field_detach(field);
264 mailmime_field_free(field);
265 goto free;
266 }
267
268 return fields;
269
270 free:
271 clist_foreach(fields->fld_list, (clist_func) mailmime_field_detach, NULL);
272 mailmime_fields_free(fields);
273 err:
274 return NULL;
275}
276
277
278struct mailmime_content * mailmime_get_content_message(void)
279{
280 clist * list;
281 struct mailmime_composite_type * composite_type;
282 struct mailmime_type * mime_type;
283 struct mailmime_content * content;
284 char * subtype;
285
286 composite_type =
287 mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MESSAGE,
288 NULL);
289 if (composite_type == NULL)
290 goto err;
291
292 mime_type = mailmime_type_new(MAILMIME_TYPE_COMPOSITE_TYPE,
293 NULL, composite_type);
294 if (mime_type == NULL)
295 goto free_composite;
296 composite_type = NULL;
297
298 list = clist_new();
299 if (list == NULL)
300 goto free_mime_type;
301
302 subtype = strdup("rfc822");
303 if (subtype == NULL)
304 goto free_list;
305
306 content = mailmime_content_new(mime_type, subtype, list);
307 if (content == NULL)
308 goto free_subtype;
309
310 return content;
311
312 free_subtype:
313 free(subtype);
314 free_list:
315 clist_free(list);
316 free_mime_type:
317 mailmime_type_free(mime_type);
318 free_composite:
319 if (composite_type != NULL)
320 mailmime_composite_type_free(composite_type);
321 err:
322 return NULL;
323}
324
325struct mailmime_content * mailmime_get_content_text(void)
326{
327 clist * list;
328 struct mailmime_discrete_type * discrete_type;
329 struct mailmime_type * mime_type;
330 struct mailmime_content * content;
331 char * subtype;
332
333 discrete_type = mailmime_discrete_type_new(MAILMIME_DISCRETE_TYPE_TEXT,
334 NULL);
335 if (discrete_type == NULL)
336 goto err;
337
338 mime_type = mailmime_type_new(MAILMIME_TYPE_DISCRETE_TYPE,
339 discrete_type, NULL);
340 if (mime_type == NULL)
341 goto free_discrete;
342 discrete_type = NULL;
343
344 list = clist_new();
345 if (list == NULL)
346 goto free_type;
347
348 subtype = strdup("plain");
349 if (subtype == NULL)
350 goto free_list;
351
352 content = mailmime_content_new(mime_type, subtype, list);
353 if (content == NULL)
354 goto free_subtype;
355
356 return content;
357
358 free_subtype:
359 free(subtype);
360 free_list:
361 clist_free(list);
362 free_type:
363 mailmime_type_free(mime_type);
364 free_discrete:
365 if (discrete_type != NULL)
366 mailmime_discrete_type_free(discrete_type);
367 err:
368 return NULL;
369}
370
371
372
373
374
375
376
377
378/* mailmime build */
379
380
381#if 0
382struct mailmime *
383mailmime_new_message_file(char * filename)
384{
385 struct mailmime_content * content;
386 struct mailmime * build_info;
387 struct mailmime_data * msg_content;
388 struct mailmime_fields * mime_fields;
389
390 content = mailmime_get_content_message();
391 if (content == NULL) {
392 goto err;
393 }
394
395 mime_fields = mailmime_fields_new_with_version(NULL, NULL,
396 NULL, NULL, NULL);
397 if (mime_fields == NULL)
398 goto free_content;
399
400 msg_content = mailmime_data_new(MAILMIME_DATA_FILE, MAILMIME_MECHANISM_8BIT,
401 1, NULL, 0, filename);
402 if (msg_content == NULL)
403 goto free_fields;
404
405 build_info = mailmime_new(MAILMIME_MESSAGE,
406 NULL, 0, mime_fields, content,
407 msg_content, NULL, NULL, NULL, NULL, NULL);
408 if (build_info == NULL)
409 goto free_msg_content;
410
411 return build_info;
412
413 free_msg_content:
414 mailmime_data_free(msg_content);
415 free_fields:
416 mailmime_fields_free(mime_fields);
417 free_content:
418 mailmime_content_free(content);
419 err:
420 return NULL;
421}
422
423struct mailmime *
424mailmime_new_message_text(char * data_str, size_t length)
425{
426 struct mailmime_content * content;
427 struct mailmime * build_info;
428 struct mailmime_data * msg_content;
429 struct mailmime_fields * mime_fields;
430
431 content = mailmime_get_content_message();
432 if (content == NULL) {
433 goto err;
434 }
435
436 mime_fields = mailmime_fields_new_with_version(NULL, NULL,
437 NULL, NULL, NULL);
438 if (mime_fields == NULL)
439 goto free_fields;
440
441 msg_content = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_8BIT,
442 1, data_str, length, NULL);
443 if (msg_content == NULL)
444 goto free_content;
445
446 build_info = mailmime_new(MAILMIME_MESSAGE,
447 NULL, 0, mime_fields, content,
448 msg_content, NULL, NULL, NULL,
449 NULL, NULL);
450 if (build_info == NULL)
451 goto free_msg_content;
452
453 return build_info;
454
455 free_msg_content:
456 mailmime_data_free(msg_content);
457 free_fields:
458 mailmime_fields_free(mime_fields);
459 free_content:
460 mailmime_content_free(content);
461 err:
462 return NULL;
463}
464#endif
465
466struct mailmime *
467mailmime_new_message_data(struct mailmime * msg_mime)
468{
469 struct mailmime_content * content;
470 struct mailmime * build_info;
471 struct mailmime_fields * mime_fields;
472
473 content = mailmime_get_content_message();
474 if (content == NULL)
475 goto err;
476
477 mime_fields = mailmime_fields_new_with_version(NULL, NULL,
478 NULL, NULL, NULL);
479 if (mime_fields == NULL)
480 goto free_content;
481
482 build_info = mailmime_new(MAILMIME_MESSAGE,
483 NULL, 0, mime_fields, content,
484 NULL, NULL, NULL, NULL,
485 NULL, msg_mime);
486 if (build_info == NULL)
487 goto free_fields;
488
489 return build_info;
490
491 free_fields:
492 mailmime_fields_free(mime_fields);
493 free_content:
494 mailmime_content_free(content);
495 err:
496 return NULL;
497}
498
499#define MAX_MESSAGE_ID 512
500
501static char * generate_boundary()
502{
503 char id[MAX_MESSAGE_ID];
504 time_t now;
505 char name[MAX_MESSAGE_ID];
506 long value;
507
508 now = time(NULL);
509 value = random();
510
511 gethostname(name, MAX_MESSAGE_ID);
512 snprintf(id, MAX_MESSAGE_ID, "%lx_%lx_%x", now, value, getpid());
513
514 return strdup(id);
515}
516
517struct mailmime *
518mailmime_new_empty(struct mailmime_content * content,
519 struct mailmime_fields * mime_fields)
520{
521 struct mailmime * build_info;
522 clist * list;
523 int r;
524 int mime_type;
525
526 list = NULL;
527
528 switch (content->ct_type->tp_type) {
529 case MAILMIME_TYPE_DISCRETE_TYPE:
530 mime_type = MAILMIME_SINGLE;
531 break;
532
533 case MAILMIME_TYPE_COMPOSITE_TYPE:
534 switch (content->ct_type->tp_data.tp_composite_type->ct_type) {
535 case MAILMIME_COMPOSITE_TYPE_MULTIPART:
536 mime_type = MAILMIME_MULTIPLE;
537 break;
538
539 case MAILMIME_COMPOSITE_TYPE_MESSAGE:
540 if (strcasecmp(content->ct_subtype, "rfc822") == 0)
541 mime_type = MAILMIME_MESSAGE;
542 else
543 mime_type = MAILMIME_SINGLE;
544 break;
545
546 default:
547 goto err;
548 }
549 break;
550
551 default:
552 goto err;
553 }
554
555 if (mime_type == MAILMIME_MULTIPLE) {
556 char * attr_name;
557 char * attr_value;
558 struct mailmime_parameter * param;
559 clist * parameters;
560 char * boundary;
561
562 list = clist_new();
563 if (list == NULL)
564 goto err;
565
566 attr_name = strdup("boundary");
567 if (attr_name == NULL)
568 goto free_list;
569
570 boundary = generate_boundary();
571 attr_value = boundary;
572 if (attr_name == NULL) {
573 free(attr_name);
574 goto free_list;
575 }
576
577 param = mailmime_parameter_new(attr_name, attr_value);
578 if (param == NULL) {
579 free(attr_value);
580 free(attr_name);
581 goto free_list;
582 }
583
584 if (content->ct_parameters == NULL) {
585 parameters = clist_new();
586 if (parameters == NULL) {
587 mailmime_parameter_free(param);
588 goto free_list;
589 }
590 }
591 else
592 parameters = content->ct_parameters;
593
594 r = clist_append(parameters, param);
595 if (r != 0) {
596 clist_free(parameters);
597 mailmime_parameter_free(param);
598 goto free_list;
599 }
600
601 if (content->ct_parameters == NULL)
602 content->ct_parameters = parameters;
603 }
604
605 build_info = mailmime_new(mime_type,
606 NULL, 0, mime_fields, content,
607 NULL, NULL, NULL, list,
608 NULL, NULL);
609 if (build_info == NULL) {
610 clist_free(list);
611 return NULL;
612 }
613
614 return build_info;
615
616 free_list:
617 clist_free(list);
618 err:
619 return NULL;
620}
621
622
623int
624mailmime_new_with_content(const char * content_type,
625 struct mailmime_fields * mime_fields,
626 struct mailmime ** result)
627{
628 int r;
629 size_t cur_token;
630 struct mailmime_content * content;
631 struct mailmime * build_info;
632#if 0
633 int mime_type;
634#endif
635 int res;
636
637 cur_token = 0;
638 r = mailmime_content_parse(content_type, strlen(content_type),
639 &cur_token,
640 &content);
641 if (r != MAILIMF_NO_ERROR) {
642 res = r;
643 goto err;
644 }
645
646#if 0
647 switch (content->type->type) {
648 case MAILMIME_TYPE_DISCRETE_TYPE:
649 mime_type = MAILMIME_SINGLE;
650 break;
651
652 case MAILMIME_TYPE_COMPOSITE_TYPE:
653 switch (content->type->composite_type->type) {
654 case MAILMIME_COMPOSITE_TYPE_MULTIPART:
655 mime_type = MAILMIME_MULTIPLE;
656 break;
657
658 case MAILMIME_COMPOSITE_TYPE_MESSAGE:
659 if (strcasecmp(content->subtype, "rfc822") == 0)
660 mime_type = MAILMIME_MESSAGE;
661 else
662 mime_type = MAILMIME_SINGLE;
663 break;
664
665 default:
666 res = MAILIMF_ERROR_INVAL;
667 goto free;
668 }
669 break;
670
671 default:
672 res = MAILIMF_ERROR_INVAL;
673 goto free;
674 }
675#endif
676
677 build_info = mailmime_new_empty(content, mime_fields);
678 if (build_info == NULL) {
679 res = MAILIMF_ERROR_MEMORY;
680 goto free;
681 }
682
683 * result = build_info;
684
685 return MAILIMF_NO_ERROR;
686
687 free:
688 mailmime_content_free(content);
689 err:
690 return res;
691}
692
693int mailmime_set_preamble_file(struct mailmime * build_info,
694 char * filename)
695{
696 struct mailmime_data * data;
697
698 data = mailmime_data_new(MAILMIME_DATA_FILE, MAILMIME_MECHANISM_8BIT,
699 0, NULL, 0, filename);
700 if (data == NULL)
701 return MAILIMF_ERROR_MEMORY;
702
703 build_info->mm_data.mm_multipart.mm_preamble = data;
704
705 return MAILIMF_NO_ERROR;
706}
707
708int mailmime_set_epilogue_file(struct mailmime * build_info,
709 char * filename)
710{
711 struct mailmime_data * data;
712
713 data = mailmime_data_new(MAILMIME_DATA_FILE, MAILMIME_MECHANISM_8BIT,
714 0, NULL, 0, filename);
715 if (data == NULL)
716 return MAILIMF_ERROR_MEMORY;
717
718 build_info->mm_data.mm_multipart.mm_epilogue = data;
719
720 return MAILIMF_NO_ERROR;
721}
722
723int mailmime_set_preamble_text(struct mailmime * build_info,
724 char * data_str, size_t length)
725{
726 struct mailmime_data * data;
727
728 data = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_8BIT,
729 0, data_str, length, NULL);
730 if (data == NULL)
731 return MAILIMF_ERROR_MEMORY;
732
733 build_info->mm_data.mm_multipart.mm_preamble = data;
734
735 return MAILIMF_NO_ERROR;
736}
737
738int mailmime_set_epilogue_text(struct mailmime * build_info,
739 char * data_str, size_t length)
740{
741 struct mailmime_data * data;
742
743 data = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_8BIT,
744 0, data_str, length, NULL);
745 if (data == NULL)
746 return MAILIMF_ERROR_MEMORY;
747
748 build_info->mm_data.mm_multipart.mm_epilogue = data;
749
750 return MAILIMF_NO_ERROR;
751}
752
753
754int mailmime_set_body_file(struct mailmime * build_info,
755 char * filename)
756{
757 int encoding;
758 struct mailmime_data * data;
759
760 encoding = mailmime_transfer_encoding_get(build_info->mm_mime_fields);
761
762 data = mailmime_data_new(MAILMIME_DATA_FILE, encoding,
763 0, NULL, 0, filename);
764 if (data == NULL)
765 return MAILIMF_ERROR_MEMORY;
766
767 build_info->mm_data.mm_single = data;
768
769 return MAILIMF_NO_ERROR;
770}
771
772int mailmime_set_body_text(struct mailmime * build_info,
773 char * data_str, size_t length)
774{
775 int encoding;
776 struct mailmime_data * data;
777
778 encoding = mailmime_transfer_encoding_get(build_info->mm_mime_fields);
779
780 data = mailmime_data_new(MAILMIME_DATA_TEXT, encoding,
781 0, data_str, length, NULL);
782 if (data == NULL)
783 return MAILIMF_ERROR_MEMORY;
784
785 build_info->mm_data.mm_single = data;
786
787 return MAILIMF_NO_ERROR;
788}
789
790
791/* add a part as subpart of a mime part */
792
793int mailmime_add_part(struct mailmime * build_info,
794 struct mailmime * part)
795{
796 int r;
797
798 if (build_info->mm_type == MAILMIME_MESSAGE) {
799 build_info->mm_data.mm_message.mm_msg_mime = part;
800 part->mm_parent_type = MAILMIME_MESSAGE;
801 part->mm_parent = build_info;
802 }
803 else if (build_info->mm_type == MAILMIME_MULTIPLE) {
804 r = clist_append(build_info->mm_data.mm_multipart.mm_mp_list, part);
805 if (r != 0)
806 return MAILIMF_ERROR_MEMORY;
807
808 part->mm_parent_type = MAILMIME_MULTIPLE;
809 part->mm_parent = build_info;
810 part->mm_multipart_pos =
811 clist_end(build_info->mm_data.mm_multipart.mm_mp_list);
812 }
813 else {
814 return MAILIMF_ERROR_INVAL;
815 }
816 return MAILIMF_NO_ERROR;
817}
818
819/* detach part from parent */
820
821void mailmime_remove_part(struct mailmime * mime)
822{
823 struct mailmime * parent;
824
825 parent = mime->mm_parent;
826 if (parent == NULL)
827 return;
828
829 switch (mime->mm_parent_type) {
830 case MAILMIME_MESSAGE:
831 mime->mm_parent = NULL;
832 parent->mm_data.mm_message.mm_msg_mime = NULL;
833 break;
834
835 case MAILMIME_MULTIPLE:
836 mime->mm_parent = NULL;
837 clist_delete(parent->mm_data.mm_multipart.mm_mp_list,
838 mime->mm_multipart_pos);
839 break;
840 }
841}
842
843
844/*
845 attach a part to a mime part and create multipart/mixed
846 when needed, when the parent part has already some part
847 attached to it.
848*/
849
850int mailmime_smart_add_part(struct mailmime * mime,
851 struct mailmime * mime_sub)
852{
853 struct mailmime * saved_sub;
854 struct mailmime * mp;
855 int res;
856 int r;
857
858 switch (mime->mm_type) {
859 case MAILMIME_SINGLE:
860 res = MAILIMF_ERROR_INVAL;
861 goto err;
862
863 case MAILMIME_MULTIPLE:
864 r = mailmime_add_part(mime, mime_sub);
865 if (r != MAILIMF_NO_ERROR) {
866 res = MAILIMF_ERROR_MEMORY;
867 goto err;
868 }
869
870 return MAILIMF_NO_ERROR;
871 }
872
873 /* MAILMIME_MESSAGE */
874
875 if (mime->mm_data.mm_message.mm_msg_mime == NULL) {
876 /* there is no subpart, we can simply attach it */
877
878 r = mailmime_add_part(mime, mime_sub);
879 if (r != MAILIMF_NO_ERROR) {
880 res = MAILIMF_ERROR_MEMORY;
881 goto err;
882 }
883
884 return MAILIMF_NO_ERROR;
885 }
886
887 if (mime->mm_data.mm_message.mm_msg_mime->mm_type == MAILMIME_MULTIPLE) {
888 /* in case the subpart is multipart, simply attach it to the subpart */
889
890 return mailmime_add_part(mime->mm_data.mm_message.mm_msg_mime, mime_sub);
891 }
892
893 /* we save the current subpart, ... */
894
895 saved_sub = mime->mm_data.mm_message.mm_msg_mime;
896
897 /* create a multipart */
898
899 mp = mailmime_multiple_new("multipart/mixed");
900 if (mp == NULL) {
901 res = MAILIMF_ERROR_MEMORY;
902 goto err;
903 }
904
905 /* detach the saved subpart from the parent */
906
907 mailmime_remove_part(saved_sub);
908
909 /* the created multipart is the new child of the parent */
910
911 r = mailmime_add_part(mime, mp);
912 if (r != MAILIMF_NO_ERROR) {
913 res = MAILIMF_ERROR_MEMORY;
914 goto free_mp;
915 }
916
917 /* then, attach the saved subpart and ... */
918
919 r = mailmime_add_part(mp, saved_sub);
920 if (r != MAILIMF_NO_ERROR) {
921 res = MAILIMF_ERROR_MEMORY;
922 goto free_saved_sub;
923 }
924
925 /* the given part to the parent */
926
927 r = mailmime_add_part(mp, mime_sub);
928 if (r != MAILIMF_NO_ERROR) {
929 res = MAILIMF_ERROR_MEMORY;
930 goto free_saved_sub;
931 }
932
933 return MAILIMF_NO_ERROR;
934
935 free_mp:
936 mailmime_free(mp);
937 free_saved_sub:
938 mailmime_free(saved_sub);
939 err:
940 return res;
941}
942
943
944
945/* detach part from parent and free it only if the part has no child */
946
947int mailmime_smart_remove_part(struct mailmime * mime)
948{
949 struct mailmime * parent;
950 int res;
951
952 parent = mime->mm_parent;
953 if (parent == NULL) {
954 res = MAILIMF_ERROR_INVAL;
955 goto err;
956 }
957
958 switch (mime->mm_type) {
959 case MAILMIME_MESSAGE:
960 if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
961 res = MAILIMF_ERROR_INVAL;
962 goto err;
963 }
964
965 mailmime_remove_part(mime);
966
967 mailmime_free(mime);
968
969 return MAILIMF_NO_ERROR;
970
971 case MAILMIME_MULTIPLE:
972 if (!clist_isempty(mime->mm_data.mm_multipart.mm_mp_list)) {
973 res = MAILIMF_ERROR_INVAL;
974 goto err;
975 }
976
977 mailmime_remove_part(mime);
978
979 mailmime_free(mime);
980
981 return MAILIMF_NO_ERROR;
982
983 case MAILMIME_SINGLE:
984 mailmime_remove_part(mime);
985
986 mailmime_free(mime);
987
988 return MAILIMF_NO_ERROR;
989
990 default:
991 return MAILIMF_ERROR_INVAL;
992 }
993
994 err:
995 return res;
996}
997
998
999/* create a mailmime_content structure (Content-Type field) */
1000
1001struct mailmime_content * mailmime_content_new_with_str(const char * str)
1002{
1003 int r;
1004 size_t cur_token;
1005 struct mailmime_content * content;
1006
1007 cur_token = 0;
1008 r = mailmime_content_parse(str, strlen(str), &cur_token, &content);
1009 if (r != MAILIMF_NO_ERROR)
1010 return NULL;
1011
1012 return content;
1013}
1014
1015/* create MIME fields with only the field Content-Transfer-Encoding */
1016
1017struct mailmime_fields * mailmime_fields_new_encoding(int type)
1018{
1019 struct mailmime_mechanism * encoding;
1020 struct mailmime_fields * mime_fields;
1021
1022 encoding = mailmime_mechanism_new(type, NULL);
1023 if (encoding == NULL)
1024 goto err;
1025
1026 mime_fields = mailmime_fields_new_with_data(encoding,
1027 NULL, NULL, NULL, NULL);
1028 if (mime_fields == NULL)
1029 goto free;
1030
1031 return mime_fields;
1032
1033 free:
1034 mailmime_mechanism_free(encoding);
1035 err:
1036 return NULL;
1037}
1038
1039
1040/* create a multipart MIME part */
1041
1042struct mailmime * mailmime_multiple_new(const char * type)
1043{
1044 struct mailmime_fields * mime_fields;
1045 struct mailmime_content * content;
1046 struct mailmime * mp;
1047
1048 mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT);
1049 if (mime_fields == NULL)
1050 goto err;
1051
1052 content = mailmime_content_new_with_str(type);
1053 if (content == NULL)
1054 goto free_fields;
1055
1056 mp = mailmime_new_empty(content, mime_fields);
1057 if (mp == NULL)
1058 goto free_content;
1059
1060 return mp;
1061
1062 free_content:
1063 mailmime_content_free(content);
1064 free_fields:
1065 mailmime_fields_free(mime_fields);
1066 err:
1067 return NULL;
1068}
1069
1070
1071
1072void mailmime_set_imf_fields(struct mailmime * build_info,
1073 struct mailimf_fields * mm_fields)
1074{
1075 build_info->mm_data.mm_message.mm_fields = mm_fields;
1076}
1077
1078#if 0
1079struct mailmime_content * mailmime_get_content(char * mime_type)
1080{
1081 struct mailmime_content *content;
1082 int r;
1083 size_t cur_token;
1084
1085 cur_token = 0;
1086 r = mailmime_content_parse(mime_type, strlen(mime_type),
1087 &cur_token, &content);
1088 if (r != MAILIMF_NO_ERROR)
1089 return NULL;
1090
1091 return content;
1092}
1093#endif
1094
1095
1096
1097
1098struct mailmime_disposition *
1099mailmime_disposition_new_with_data(int type,
1100 char * filename, char * creation_date, char * modification_date,
1101 char * read_date, size_t size)
1102{
1103 struct mailmime_disposition_type * dsp_type;
1104 clist * list;
1105 int r;
1106 struct mailmime_disposition_parm * parm;
1107 struct mailmime_disposition * dsp;
1108
1109 dsp_type = mailmime_disposition_type_new(type, NULL);
1110 if (dsp_type == NULL)
1111 goto err;
1112
1113 list = clist_new();
1114 if (list == NULL)
1115 goto free_dsp_type;
1116
1117 if (filename != NULL) {
1118 parm = mailmime_disposition_parm_new(MAILMIME_DISPOSITION_PARM_FILENAME,
1119 filename, NULL, NULL, NULL, 0, NULL);
1120 if (parm == NULL)
1121 goto free_list;
1122
1123 r = clist_append(list, parm);
1124 if (r < 0) {
1125 mailmime_disposition_parm_free(parm);
1126 goto free_list;
1127 }
1128 }
1129
1130 if (creation_date != NULL) {
1131 parm = mailmime_disposition_parm_new(MAILMIME_DISPOSITION_PARM_CREATION_DATE,
1132 NULL, creation_date, NULL, NULL, 0, NULL);
1133 if (parm == NULL)
1134 goto free_list;
1135
1136 r = clist_append(list, parm);
1137 if (r < 0) {
1138 mailmime_disposition_parm_free(parm);
1139 goto free_list;
1140 }
1141 }
1142
1143 if (modification_date != NULL) {
1144 parm = mailmime_disposition_parm_new(MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE,
1145 NULL, NULL, modification_date, NULL, 0, NULL);
1146 if (parm == NULL)
1147 goto free_list;
1148
1149 r = clist_append(list, parm);
1150 if (r < 0) {
1151 mailmime_disposition_parm_free(parm);
1152 goto free_list;
1153 }
1154 }
1155
1156 if (read_date != NULL) {
1157 parm = mailmime_disposition_parm_new(MAILMIME_DISPOSITION_PARM_READ_DATE,
1158 NULL, NULL, NULL, read_date, 0, NULL);
1159 if (parm == NULL)
1160 goto free_list;
1161
1162 r = clist_append(list, parm);
1163 if (r < 0) {
1164 mailmime_disposition_parm_free(parm);
1165 goto free_list;
1166 }
1167 }
1168
1169 if (size != (size_t) -1) {
1170 parm = mailmime_disposition_parm_new(MAILMIME_DISPOSITION_PARM_SIZE,
1171 NULL, NULL, NULL, NULL, size, NULL);
1172 if (parm == NULL)
1173 goto free_list;
1174
1175 r = clist_append(list, parm);
1176 if (r < 0) {
1177 mailmime_disposition_parm_free(parm);
1178 goto free_list;
1179 }
1180 }
1181
1182 dsp = mailmime_disposition_new(dsp_type, list);
1183
1184 return dsp;
1185
1186 free_list:
1187 clist_foreach(list, (clist_func) mailmime_disposition_parm_free, NULL);
1188 clist_free(list);
1189 free_dsp_type:
1190 mailmime_disposition_type_free(dsp_type);
1191 err:
1192 return NULL;
1193}
1194
1195
1196static void mailmime_disposition_single_fields_init(struct
1197 mailmime_single_fields * single_fields,
1198 struct mailmime_disposition * fld_disposition)
1199{
1200 clistiter * cur;
1201
1202 single_fields->fld_disposition = fld_disposition;
1203
1204 for(cur = clist_begin(fld_disposition->dsp_parms) ; cur != NULL ;
1205 cur = clist_next(cur)) {
1206 struct mailmime_disposition_parm * param;
1207
1208 param = clist_content(cur);
1209
1210 switch (param->pa_type) {
1211 case MAILMIME_DISPOSITION_PARM_FILENAME:
1212 single_fields->fld_disposition_filename = param->pa_data.pa_filename;
1213 break;
1214
1215 case MAILMIME_DISPOSITION_PARM_CREATION_DATE:
1216 single_fields->fld_disposition_creation_date =
1217 param->pa_data.pa_creation_date;
1218 break;
1219
1220 case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE:
1221 single_fields->fld_disposition_modification_date =
1222 param->pa_data.pa_modification_date;
1223 break;
1224
1225 case MAILMIME_DISPOSITION_PARM_READ_DATE:
1226 single_fields->fld_disposition_read_date =
1227 param->pa_data.pa_read_date;
1228 break;
1229
1230 case MAILMIME_DISPOSITION_PARM_SIZE:
1231 single_fields->fld_disposition_size = param->pa_data.pa_size;
1232 break;
1233 }
1234 }
1235}
1236
1237static void mailmime_content_single_fields_init(struct
1238 mailmime_single_fields * single_fields,
1239 struct mailmime_content * fld_content)
1240{
1241 clistiter * cur;
1242
1243 single_fields->fld_content = fld_content;
1244
1245 for(cur = clist_begin(fld_content->ct_parameters) ;
1246 cur != NULL ; cur = clist_next(cur)) {
1247 struct mailmime_parameter * param;
1248
1249 param = clist_content(cur);
1250
1251 if (strcasecmp(param->pa_name, "boundary") == 0)
1252 single_fields->fld_content_boundary = param->pa_value;
1253
1254 if (strcasecmp(param->pa_name, "charset") == 0)
1255 single_fields->fld_content_charset = param->pa_value;
1256
1257 if (strcasecmp(param->pa_name, "name") == 0)
1258 single_fields->fld_content_name = param->pa_value;
1259 }
1260}
1261
1262void mailmime_single_fields_init(struct mailmime_single_fields * single_fields,
1263 struct mailmime_fields * fld_fields,
1264 struct mailmime_content * fld_content)
1265{
1266 clistiter * cur;
1267
1268 memset(single_fields, 0, sizeof(struct mailmime_single_fields));
1269
1270 if (fld_content != NULL)
1271 mailmime_content_single_fields_init(single_fields, fld_content);
1272
1273 if (fld_fields == NULL)
1274 return;
1275
1276 for(cur = clist_begin(fld_fields->fld_list) ; cur != NULL ;
1277 cur = clist_next(cur)) {
1278 struct mailmime_field * field;
1279
1280 field = clist_content(cur);
1281
1282 switch (field->fld_type) {
1283 case MAILMIME_FIELD_TYPE:
1284 mailmime_content_single_fields_init(single_fields,
1285 field->fld_data.fld_content);
1286 break;
1287
1288 case MAILMIME_FIELD_TRANSFER_ENCODING:
1289 single_fields->fld_encoding = field->fld_data.fld_encoding;
1290 break;
1291
1292 case MAILMIME_FIELD_ID:
1293 single_fields->fld_id = field->fld_data.fld_id;
1294 break;
1295
1296 case MAILMIME_FIELD_DESCRIPTION:
1297 single_fields->fld_description = field->fld_data.fld_description;
1298 break;
1299
1300 case MAILMIME_FIELD_VERSION:
1301 single_fields->fld_version = field->fld_data.fld_version;
1302 break;
1303
1304 case MAILMIME_FIELD_DISPOSITION:
1305 mailmime_disposition_single_fields_init(single_fields,
1306 field->fld_data.fld_disposition);
1307 break;
1308
1309 case MAILMIME_FIELD_LANGUAGE:
1310 single_fields->fld_language = field->fld_data.fld_language;
1311 break;
1312 }
1313 }
1314}
1315
1316struct mailmime_single_fields *
1317mailmime_single_fields_new(struct mailmime_fields * fld_fields,
1318 struct mailmime_content * fld_content)
1319{
1320 struct mailmime_single_fields * single_fields;
1321
1322 single_fields = malloc(sizeof(struct mailmime_single_fields));
1323 if (single_fields == NULL)
1324 goto err;
1325
1326 mailmime_single_fields_init(single_fields, fld_fields, fld_content);
1327
1328 return single_fields;
1329
1330 err:
1331 return NULL;
1332}
1333
1334
1335void mailmime_single_fields_free(struct mailmime_single_fields *
1336 single_fields)
1337{
1338 free(single_fields);
1339}
1340
1341struct mailmime_fields * mailmime_fields_new_filename(int dsp_type,
1342 char * filename, int encoding_type)
1343{
1344 struct mailmime_disposition * dsp;
1345 struct mailmime_mechanism * encoding;
1346 struct mailmime_fields * mime_fields;
1347
1348 dsp = mailmime_disposition_new_with_data(dsp_type,
1349 filename, NULL, NULL, NULL, (size_t) -1);
1350 if (dsp == NULL)
1351 goto err;
1352
1353 encoding = mailmime_mechanism_new(encoding_type, NULL);
1354 if (encoding == NULL)
1355 goto free_dsp;
1356
1357 mime_fields = mailmime_fields_new_with_data(encoding,
1358 NULL, NULL, dsp, NULL);
1359 if (mime_fields == NULL)
1360 goto free_encoding;
1361
1362 return mime_fields;
1363
1364 free_encoding:
1365 mailmime_encoding_free(encoding);
1366 free_dsp:
1367 mailmime_disposition_free(dsp);
1368 err:
1369 return NULL;
1370}
1371
1372struct mailmime_data *
1373mailmime_data_new_data(int encoding, int encoded,
1374 const char * data, size_t length)
1375{
1376 return mailmime_data_new(MAILMIME_DATA_TEXT, encoding, encoded, data, length, NULL);
1377}
1378
1379struct mailmime_data *
1380mailmime_data_new_file(int encoding, int encoded,
1381 char * filename)
1382{
1383 return mailmime_data_new(MAILMIME_DATA_FILE, encoding, encoded, NULL, 0, filename);
1384}
1385
diff --git a/kmicromail/libetpan/mime/mailmime_types_helper.h b/kmicromail/libetpan/mime/mailmime_types_helper.h
new file mode 100644
index 0000000..608acca
--- a/dev/null
+++ b/kmicromail/libetpan/mime/mailmime_types_helper.h
@@ -0,0 +1,165 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMIME_TYPES_HELPER_H
37
38#define MAILMIME_TYPES_HELPER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailmime_types.h>
45
46int mailmime_transfer_encoding_get(struct mailmime_fields * fields);
47
48struct mailmime_disposition *
49mailmime_disposition_new_filename(int type, char * filename);
50
51struct mailmime_fields * mailmime_fields_new_empty(void);
52
53int mailmime_fields_add(struct mailmime_fields * fields,
54 struct mailmime_field * field);
55
56struct mailmime_fields *
57mailmime_fields_new_with_data(struct mailmime_mechanism * encoding,
58 char * id,
59 char * description,
60 struct mailmime_disposition * disposition,
61 struct mailmime_language * language);
62
63struct mailmime_fields *
64mailmime_fields_new_with_version(struct mailmime_mechanism * encoding,
65 char * id,
66 char * description,
67 struct mailmime_disposition * disposition,
68 struct mailmime_language * language);
69
70struct mailmime_content * mailmime_get_content_message(void);
71struct mailmime_content * mailmime_get_content_text(void);
72/* struct mailmime_content * mailmime_get_content(char * mime_type); */
73
74#define mailmime_get_content mailmime_content_new_with_str
75
76struct mailmime_data *
77mailmime_data_new_data(int encoding, int encoded,
78 const char * data, size_t length);
79
80struct mailmime_data *
81mailmime_data_new_file(int encoding, int encoded,
82 char * filename);
83
84#if 0
85struct mailmime *
86mailmime_new_message_file(char * filename);
87
88struct mailmime *
89mailmime_new_message_text(char * data_str, size_t length);
90#endif
91
92struct mailmime *
93mailmime_new_message_data(struct mailmime * msg_mime);
94
95struct mailmime *
96mailmime_new_empty(struct mailmime_content * content,
97 struct mailmime_fields * mime_fields);
98
99int
100mailmime_new_with_content(const char * content_type,
101 struct mailmime_fields * mime_fields,
102 struct mailmime ** result);
103
104int mailmime_set_preamble_file(struct mailmime * build_info,
105 char * filename);
106
107int mailmime_set_epilogue_file(struct mailmime * build_info,
108 char * filename);
109
110int mailmime_set_preamble_text(struct mailmime * build_info,
111 char * data_str, size_t length);
112
113int mailmime_set_epilogue_text(struct mailmime * build_info,
114 char * data_str, size_t length);
115
116int mailmime_set_body_file(struct mailmime * build_info,
117 char * filename);
118
119int mailmime_set_body_text(struct mailmime * build_info,
120 char * data_str, size_t length);
121
122int mailmime_add_part(struct mailmime * build_info,
123 struct mailmime * part);
124
125void mailmime_remove_part(struct mailmime * mime);
126
127void mailmime_set_imf_fields(struct mailmime * build_info,
128 struct mailimf_fields * fields);
129
130
131struct mailmime_disposition *
132mailmime_disposition_new_with_data(int type,
133 char * filename, char * creation_date, char * modification_date,
134 char * read_date, size_t size);
135
136void mailmime_single_fields_init(struct mailmime_single_fields * single_fields,
137 struct mailmime_fields * fld_fields,
138 struct mailmime_content * fld_content);
139
140struct mailmime_single_fields *
141mailmime_single_fields_new(struct mailmime_fields * fld_fields,
142 struct mailmime_content * fld_content);
143
144void mailmime_single_fields_free(struct mailmime_single_fields *
145 single_fields);
146
147int mailmime_smart_add_part(struct mailmime * mime,
148 struct mailmime * mime_sub);
149
150int mailmime_smart_remove_part(struct mailmime * mime);
151
152struct mailmime_content * mailmime_content_new_with_str(const char * str);
153
154struct mailmime_fields * mailmime_fields_new_encoding(int type);
155
156struct mailmime * mailmime_multiple_new(const char * type);
157
158struct mailmime_fields * mailmime_fields_new_filename(int dsp_type,
159 char * filename, int encoding_type);
160
161#ifdef __cplusplus
162}
163#endif
164
165#endif
diff --git a/kmicromail/libetpan/mime/mailmime_write.c b/kmicromail/libetpan/mime/mailmime_write.c
new file mode 100644
index 0000000..5c3b1f7
--- a/dev/null
+++ b/kmicromail/libetpan/mime/mailmime_write.c
@@ -0,0 +1,1416 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailmime_write.h"
37
38#include <stdlib.h>
39#include <string.h>
40#include <time.h>
41#include <unistd.h>
42#include <sys/types.h>
43#include <sys/stat.h>
44#include <fcntl.h>
45#include <sys/mman.h>
46
47#include "mailimf_write.h"
48#include "mailmime_content.h"
49#include "mailmime_types_helper.h"
50
51#define MAX_MAIL_COL 78
52
53#ifndef TRUE
54#define TRUE 1
55#endif
56
57#ifndef FALSE
58#define FALSE 0
59#endif
60
61static int mailmime_field_write(FILE * f, int * col,
62 struct mailmime_field * field);
63
64static int mailmime_id_write(FILE * f, int * col, char * id);
65
66static int mailmime_description_write(FILE * f, int * col, char * descr);
67
68static int mailmime_version_write(FILE * f, int * col, uint32_t version);
69
70static int mailmime_encoding_write(FILE * f, int * col,
71 struct mailmime_mechanism * encoding);
72
73static int mailmime_language_write(FILE * f, int * col,
74 struct mailmime_language * language);
75
76static int mailmime_disposition_write(FILE * f, int * col,
77 struct mailmime_disposition *
78 disposition);
79
80static int
81mailmime_disposition_param_write(FILE * f, int * col,
82 struct mailmime_disposition_parm * param);
83
84static int mailmime_parameter_write(FILE * f, int * col,
85 struct mailmime_parameter * param);
86
87/*
88static int mailmime_content_write(FILE * f, int * col,
89 struct mailmime_content * content);
90*/
91
92static int mailmime_type_write(FILE * f, int * col,
93 struct mailmime_type * type);
94
95static int
96mailmime_discrete_type_write(FILE * f, int * col,
97 struct mailmime_discrete_type * discrete_type);
98
99static int
100mailmime_composite_type_write(FILE * f, int * col,
101 struct mailmime_composite_type * composite_type);
102
103static int mailmime_sub_write(FILE * f, int * col,
104 struct mailmime * build_info);
105
106
107/* ***** */
108
109int mailmime_fields_write(FILE * f, int * col, struct mailmime_fields * fields)
110{
111 int r;
112 clistiter * cur;
113
114 for(cur = clist_begin(fields->fld_list) ; cur != NULL ;
115 cur = clist_next(cur)) {
116 struct mailmime_field * field;
117
118 field = cur->data;
119 r = mailmime_field_write(f, col, field);
120 if (r != MAILIMF_NO_ERROR)
121 return r;
122 }
123
124 return MAILIMF_NO_ERROR;
125}
126
127static int mailmime_field_write(FILE * f, int * col,
128 struct mailmime_field * field)
129{
130 int r;
131
132 switch (field->fld_type) {
133 case MAILMIME_FIELD_TYPE:
134 r = mailmime_content_write(f, col, field->fld_data.fld_content);
135 break;
136
137 case MAILMIME_FIELD_TRANSFER_ENCODING:
138 r = mailmime_encoding_write(f, col, field->fld_data.fld_encoding);
139 break;
140
141 case MAILMIME_FIELD_ID:
142 r = mailmime_id_write(f, col, field->fld_data.fld_id);
143 break;
144
145 case MAILMIME_FIELD_DESCRIPTION:
146 r = mailmime_description_write(f, col, field->fld_data.fld_description);
147 break;
148
149 case MAILMIME_FIELD_VERSION:
150 r = mailmime_version_write(f, col, field->fld_data.fld_version);
151 break;
152
153 case MAILMIME_FIELD_DISPOSITION:
154 r = mailmime_disposition_write(f, col, field->fld_data.fld_disposition);
155 break;
156
157 case MAILMIME_FIELD_LANGUAGE:
158 r = mailmime_language_write(f, col, field->fld_data.fld_language);
159 break;
160
161 default:
162 r = MAILIMF_ERROR_INVAL;
163 break;
164 }
165
166 if (r != MAILIMF_NO_ERROR)
167 return r;
168
169 return MAILIMF_NO_ERROR;
170}
171
172static int mailmime_id_write(FILE * f, int * col, char * id)
173{
174 int r;
175
176 r = mailimf_string_write(f, col, "Content-ID: ", 12);
177 if (r != MAILIMF_NO_ERROR)
178 return r;
179
180 r = mailimf_string_write(f, col, "<", 1);
181 if (r != MAILIMF_NO_ERROR)
182 return r;
183
184 r = mailimf_string_write(f, col, id, strlen(id));
185 if (r != MAILIMF_NO_ERROR)
186 return r;
187
188 r = mailimf_string_write(f, col, ">", 1);
189 if (r != MAILIMF_NO_ERROR)
190 return r;
191
192 r = mailimf_string_write(f, col, "\r\n", 2);
193 if (r != MAILIMF_NO_ERROR)
194 return r;
195#if 0
196 * col = 0;
197#endif
198
199 return MAILIMF_NO_ERROR;
200}
201
202static int mailmime_description_write(FILE * f, int * col, char * descr)
203{
204 int r;
205
206 r = mailimf_string_write(f, col, "Content-Description: ", 21);
207 if (r != MAILIMF_NO_ERROR)
208 return r;
209
210 r = mailimf_string_write(f, col, descr, strlen(descr));
211 if (r != MAILIMF_NO_ERROR)
212 return r;
213
214 r = mailimf_string_write(f, col, "\r\n", 2);
215 if (r != MAILIMF_NO_ERROR)
216 return r;
217#if 0
218 * col = 0;
219#endif
220
221 return MAILIMF_NO_ERROR;
222}
223
224static int mailmime_version_write(FILE * f, int * col, uint32_t version)
225{
226 int r;
227 char versionstr[40];
228
229 r = mailimf_string_write(f, col, "MIME-Version: ", 14);
230 if (r != MAILIMF_NO_ERROR)
231 return r;
232
233 snprintf(versionstr, 40, "%i.%i", version >> 16, version & 0xFFFF);
234
235 r = mailimf_string_write(f, col, versionstr, strlen(versionstr));
236 if (r != MAILIMF_NO_ERROR)
237 return r;
238
239 r = mailimf_string_write(f, col, "\r\n", 2);
240 if (r != MAILIMF_NO_ERROR)
241 return r;
242#if 0
243 * col = 0;
244#endif
245
246 return MAILIMF_NO_ERROR;
247}
248
249static int mailmime_encoding_write(FILE * f, int * col,
250 struct mailmime_mechanism * encoding)
251{
252 int r;
253
254 r = mailimf_string_write(f, col, "Content-Transfer-Encoding: ", 27);
255 if (r != MAILIMF_NO_ERROR)
256 return r;
257
258 switch (encoding->enc_type) {
259 case MAILMIME_MECHANISM_7BIT:
260 r = mailimf_string_write(f, col, "7bit", 4);
261 break;
262
263 case MAILMIME_MECHANISM_8BIT:
264 r = mailimf_string_write(f, col, "8bit", 4);
265 break;
266
267 case MAILMIME_MECHANISM_BINARY:
268 r = mailimf_string_write(f, col, "binary", 6);
269 break;
270
271 case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
272 r = mailimf_string_write(f, col, "quoted-printable", 16);
273 break;
274
275 case MAILMIME_MECHANISM_BASE64:
276 r = mailimf_string_write(f, col, "base64", 6);
277 break;
278
279 case MAILMIME_MECHANISM_TOKEN:
280 r = mailimf_string_write(f, col, encoding->enc_token,
281 strlen(encoding->enc_token));
282 break;
283
284 default:
285 r = MAILIMF_ERROR_INVAL;
286 break;
287 }
288
289 if (r != MAILIMF_NO_ERROR)
290 return r;
291
292 r = mailimf_string_write(f, col, "\r\n", 2);
293 if (r != MAILIMF_NO_ERROR)
294 return r;
295#if 0
296 * col = 0;
297#endif
298
299 return MAILIMF_NO_ERROR;
300}
301
302static int mailmime_language_write(FILE * f, int * col,
303 struct mailmime_language * language)
304{
305 int r;
306 clistiter * cur;
307 int first;
308
309 r = mailimf_string_write(f, col, "Content-Language: ", 18);
310 if (r != MAILIMF_NO_ERROR)
311 return r;
312
313 first = TRUE;
314
315 for(cur = clist_begin(language->lg_list) ; cur != NULL ;
316 cur = clist_next(cur)) {
317 char * lang;
318 size_t len;
319
320 lang = clist_content(cur);
321 len = strlen(lang);
322
323 if (!first) {
324 r = mailimf_string_write(f, col, ", ", 2);
325 if (r != MAILIMF_NO_ERROR)
326 return r;
327 }
328 else {
329 first = FALSE;
330 }
331
332 if (* col > 1) {
333
334 if (* col + len > MAX_MAIL_COL) {
335 r = mailimf_string_write(f, col, "\r\n ", 3);
336 if (r != MAILIMF_NO_ERROR)
337 return r;
338#if 0
339 * col = 1;
340#endif
341 }
342 }
343
344 r = mailimf_string_write(f, col, lang, len);
345 if (r != MAILIMF_NO_ERROR)
346 return r;
347 }
348
349 r = mailimf_string_write(f, col, "\r\n", 2);
350 if (r != MAILIMF_NO_ERROR)
351 return r;
352#if 0
353 * col = 0;
354#endif
355
356 return MAILIMF_NO_ERROR;
357}
358
359static int mailmime_disposition_write(FILE * f, int * col,
360 struct mailmime_disposition *
361 disposition)
362{
363 struct mailmime_disposition_type * dsp_type;
364 int r;
365 clistiter * cur;
366
367 dsp_type = disposition->dsp_type;
368
369 r = mailimf_string_write(f, col, "Content-Disposition: ", 21);
370 if (r != MAILIMF_NO_ERROR)
371 return r;
372
373 switch (dsp_type->dsp_type) {
374 case MAILMIME_DISPOSITION_TYPE_INLINE:
375 r = mailimf_string_write(f, col, "inline", 6);
376 break;
377
378 case MAILMIME_DISPOSITION_TYPE_ATTACHMENT:
379 r = mailimf_string_write(f, col, "attachment", 10);
380 break;
381
382 case MAILMIME_DISPOSITION_TYPE_EXTENSION:
383 r = mailimf_string_write(f, col, dsp_type->dsp_extension,
384 strlen(dsp_type->dsp_extension));
385 break;
386
387 default:
388 r = MAILIMF_ERROR_INVAL;
389 break;
390 }
391
392 if (r != MAILIMF_NO_ERROR)
393 return r;
394
395 for(cur = clist_begin(disposition->dsp_parms) ;
396 cur != NULL ; cur = clist_next(cur)) {
397 struct mailmime_disposition_parm * param;
398
399 param = cur->data;
400
401 r = mailimf_string_write(f, col, "; ", 2);
402 if (r != MAILIMF_NO_ERROR)
403 return r;
404
405 r = mailmime_disposition_param_write(f, col, param);
406 if (r != MAILIMF_NO_ERROR)
407 return r;
408 }
409
410 r = mailimf_string_write(f, col, "\r\n", 2);
411 if (r != MAILIMF_NO_ERROR)
412 return r;
413
414 return MAILIMF_NO_ERROR;
415}
416
417static int
418mailmime_disposition_param_write(FILE * f, int * col,
419 struct mailmime_disposition_parm * param)
420{
421 size_t len;
422 char sizestr[20];
423 int r;
424
425 switch (param->pa_type) {
426 case MAILMIME_DISPOSITION_PARM_FILENAME:
427 len = strlen("filename=") + strlen(param->pa_data.pa_filename);
428 break;
429
430 case MAILMIME_DISPOSITION_PARM_CREATION_DATE:
431 len = strlen("creation-date=") + strlen(param->pa_data.pa_creation_date);
432 break;
433
434 case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE:
435 len = strlen("modification-date=") +
436 strlen(param->pa_data.pa_modification_date);
437 break;
438
439 case MAILMIME_DISPOSITION_PARM_READ_DATE:
440 len = strlen("read-date=") + strlen(param->pa_data.pa_read_date);
441 break;
442
443 case MAILMIME_DISPOSITION_PARM_SIZE:
444 snprintf(sizestr, 20, "%u", param->pa_data.pa_size);
445 len = strlen("size=") + strlen(sizestr);
446 break;
447
448 case MAILMIME_DISPOSITION_PARM_PARAMETER:
449 len = strlen(param->pa_data.pa_parameter->pa_name) + 1 +
450 strlen(param->pa_data.pa_parameter->pa_value);
451 break;
452
453 default:
454 return MAILIMF_ERROR_INVAL;
455 }
456
457 if (* col > 1) {
458
459 if (* col + len > MAX_MAIL_COL) {
460 r = mailimf_string_write(f, col, "\r\n ", 3);
461 if (r != MAILIMF_NO_ERROR)
462 return r;
463#if 0
464 * col = 1;
465#endif
466 }
467 }
468
469 switch (param->pa_type) {
470 case MAILMIME_DISPOSITION_PARM_FILENAME:
471 r = mailimf_string_write(f, col, "filename=", 9);
472 if (r != MAILIMF_NO_ERROR)
473 return r;
474
475 r = mailimf_quoted_string_write(f, col,
476 param->pa_data.pa_filename, strlen(param->pa_data.pa_filename));
477 if (r != MAILIMF_NO_ERROR)
478 return r;
479 break;
480
481 case MAILMIME_DISPOSITION_PARM_CREATION_DATE:
482 r = mailimf_string_write(f, col, "creation-date=", 14);
483 if (r != MAILIMF_NO_ERROR)
484 return r;
485
486 r = mailimf_quoted_string_write(f, col, param->pa_data.pa_creation_date,
487 strlen(param->pa_data.pa_creation_date));
488 if (r != MAILIMF_NO_ERROR)
489 return r;
490 break;
491
492 case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE:
493 r = mailimf_string_write(f, col, "modification-date=", 18);
494 if (r != MAILIMF_NO_ERROR)
495 return r;
496
497 r = mailimf_quoted_string_write(f, col,
498 param->pa_data.pa_modification_date,
499 strlen(param->pa_data.pa_modification_date));
500 if (r != MAILIMF_NO_ERROR)
501 return r;
502 break;
503
504 case MAILMIME_DISPOSITION_PARM_READ_DATE:
505 r = mailimf_string_write(f, col, "read-date=", 10);
506 if (r != MAILIMF_NO_ERROR)
507 return r;
508
509 r = mailimf_quoted_string_write(f, col, param->pa_data.pa_read_date,
510 strlen(param->pa_data.pa_read_date));
511 if (r != MAILIMF_NO_ERROR)
512 return r;
513 break;
514
515 case MAILMIME_DISPOSITION_PARM_SIZE:
516 r = mailimf_string_write(f, col, "size=", 5);
517 if (r != MAILIMF_NO_ERROR)
518 return r;
519
520 r = mailimf_string_write(f, col, sizestr, strlen(sizestr));
521 if (r != MAILIMF_NO_ERROR)
522 return r;
523 break;
524
525 case MAILMIME_DISPOSITION_PARM_PARAMETER:
526 r = mailmime_parameter_write(f, col, param->pa_data.pa_parameter);
527 if (r != MAILIMF_NO_ERROR)
528 return r;
529 break;
530 }
531
532 return MAILIMF_NO_ERROR;
533}
534
535static int mailmime_parameter_write(FILE * f, int * col,
536 struct mailmime_parameter * param)
537{
538 int r;
539
540 r = mailimf_string_write(f, col, param->pa_name,
541 strlen(param->pa_name));
542 if (r != MAILIMF_NO_ERROR)
543 return r;
544
545 r = mailimf_string_write(f, col, "=", 1);
546 if (r != MAILIMF_NO_ERROR)
547 return r;
548
549 r = mailimf_quoted_string_write(f, col, param->pa_value,
550 strlen(param->pa_value));
551 if (r != MAILIMF_NO_ERROR)
552 return r;
553
554 return MAILIMF_NO_ERROR;
555}
556
557int mailmime_content_type_write(FILE * f, int * col,
558 struct mailmime_content * content)
559{
560 clistiter * cur;
561 size_t len;
562 int r;
563
564 r = mailmime_type_write(f, col, content->ct_type);
565 if (r != MAILIMF_NO_ERROR)
566 return r;
567
568 r = mailimf_string_write(f, col, "/", 1);
569 if (r != MAILIMF_NO_ERROR)
570 return r;
571
572 r = mailimf_string_write(f, col, content->ct_subtype,
573 strlen(content->ct_subtype));
574 if (r != MAILIMF_NO_ERROR)
575 return r;
576
577 if (content->ct_parameters != NULL) {
578 for(cur = clist_begin(content->ct_parameters) ;
579 cur != NULL ; cur = clist_next(cur)) {
580 struct mailmime_parameter * param;
581
582 param = cur->data;
583
584 r = mailimf_string_write(f, col, "; ", 2);
585 if (r != MAILIMF_NO_ERROR)
586 return r;
587
588 len = strlen(param->pa_name) + 1 + strlen(param->pa_value);
589
590 if (* col > 1) {
591
592 if (* col + len > MAX_MAIL_COL) {
593 r = mailimf_string_write(f, col, "\r\n ", 3);
594 if (r != MAILIMF_NO_ERROR)
595 return r;
596#if 0
597 * col = 1;
598#endif
599 }
600 }
601
602 r = mailmime_parameter_write(f, col, param);
603 if (r != MAILIMF_NO_ERROR)
604 return r;
605 }
606 }
607
608 return MAILIMF_NO_ERROR;
609}
610
611int mailmime_content_write(FILE * f, int * col,
612 struct mailmime_content * content)
613{
614 int r;
615
616 r = mailimf_string_write(f, col, "Content-Type: ", 14);
617 if (r != MAILIMF_NO_ERROR)
618 return r;
619
620 r = mailmime_content_type_write(f, col, content);
621 if (r != MAILIMF_NO_ERROR)
622 return r;
623
624 r = mailimf_string_write(f, col, "\r\n", 2);
625 if (r != MAILIMF_NO_ERROR)
626 return r;
627
628 return MAILIMF_NO_ERROR;
629}
630
631static int mailmime_type_write(FILE * f, int * col,
632 struct mailmime_type * type)
633{
634 int r;
635
636 switch (type->tp_type) {
637 case MAILMIME_TYPE_DISCRETE_TYPE:
638 r = mailmime_discrete_type_write(f, col, type->tp_data.tp_discrete_type);
639 break;
640
641 case MAILMIME_TYPE_COMPOSITE_TYPE:
642 r = mailmime_composite_type_write(f, col, type->tp_data.tp_composite_type);
643 break;
644
645 default:
646 r = MAILIMF_ERROR_INVAL;
647 break;
648 }
649
650 if (r != MAILIMF_NO_ERROR)
651 return r;
652
653 return MAILIMF_NO_ERROR;
654}
655
656static int
657mailmime_discrete_type_write(FILE * f, int * col,
658 struct mailmime_discrete_type * discrete_type)
659{
660 int r;
661
662 switch (discrete_type->dt_type) {
663 case MAILMIME_DISCRETE_TYPE_TEXT:
664 r = mailimf_string_write(f, col, "text", 4);
665 break;
666
667 case MAILMIME_DISCRETE_TYPE_IMAGE:
668 r = mailimf_string_write(f, col, "image", 5);
669 break;
670
671 case MAILMIME_DISCRETE_TYPE_AUDIO:
672 r = mailimf_string_write(f, col, "audio", 5);
673 break;
674
675 case MAILMIME_DISCRETE_TYPE_VIDEO:
676 r = mailimf_string_write(f, col, "video", 5);
677 break;
678
679 case MAILMIME_DISCRETE_TYPE_APPLICATION:
680 r = mailimf_string_write(f, col, "application", 11);
681 break;
682
683 case MAILMIME_DISCRETE_TYPE_EXTENSION:
684 r = mailimf_string_write(f, col, discrete_type->dt_extension,
685 strlen(discrete_type->dt_extension));
686 break;
687
688 default:
689 r = MAILIMF_ERROR_INVAL;
690 break;
691 }
692
693 if (r != MAILIMF_NO_ERROR)
694 return r;
695
696 return MAILIMF_NO_ERROR;
697}
698
699static int
700mailmime_composite_type_write(FILE * f, int * col,
701 struct mailmime_composite_type * composite_type)
702{
703 int r;
704
705 switch (composite_type->ct_type) {
706 case MAILMIME_COMPOSITE_TYPE_MESSAGE:
707 r = mailimf_string_write(f, col, "message", 7);
708 break;
709
710 case MAILMIME_COMPOSITE_TYPE_MULTIPART:
711 r = mailimf_string_write(f, col, "multipart", 9);
712 break;
713
714 case MAILMIME_COMPOSITE_TYPE_EXTENSION:
715 r = mailimf_string_write(f, col, composite_type->ct_token,
716 strlen(composite_type->ct_token));
717 break;
718
719 default:
720 r = MAILIMF_ERROR_INVAL;
721 break;
722 }
723
724 if (r != MAILIMF_NO_ERROR)
725 return r;
726
727 return MAILIMF_NO_ERROR;
728}
729
730
731
732
733/* ****************************************************************** */
734/* message */
735
736/*
737static int mailmime_data_write(FILE * f, int * col,
738 struct mailmime_data * data,
739 int is_text);
740*/
741
742static int mailmime_text_content_write(FILE * f, int * col, int encoding,
743 int istext,
744 const char * text, size_t size);
745
746/*
747static int mailmime_base64_write(FILE * f, int * col,
748 char * text, size_t size);
749
750static int mailmime_quoted_printable_write(FILE * f, int * col, int istext,
751 char * text, size_t size);
752*/
753
754static int mailmime_part_write(FILE * f, int * col,
755 struct mailmime * build_info)
756{
757 clistiter * cur;
758 int first;
759 int r;
760 char * boundary;
761 int istext;
762
763 istext = TRUE;
764 boundary = NULL;
765
766 if (build_info->mm_content_type != NULL) {
767 if (build_info->mm_type == MAILMIME_MULTIPLE) {
768 boundary = mailmime_extract_boundary(build_info->mm_content_type);
769 if (boundary == NULL)
770 return MAILIMF_ERROR_INVAL;
771 }
772
773 if (build_info->mm_content_type->ct_type->tp_type ==
774 MAILMIME_TYPE_DISCRETE_TYPE) {
775 if (build_info->mm_content_type->ct_type->tp_data.tp_discrete_type->dt_type !=
776 MAILMIME_DISCRETE_TYPE_TEXT)
777 istext = FALSE;
778 }
779 }
780
781 switch (build_info->mm_type) {
782 case MAILMIME_SINGLE:
783
784 /* 1-part body */
785
786 if (build_info->mm_data.mm_single != NULL) {
787 r = mailmime_data_write(f, col, build_info->mm_data.mm_single, istext);
788 if (r != MAILIMF_NO_ERROR)
789 return r;
790 }
791
792 break;
793
794 case MAILMIME_MULTIPLE:
795
796 /* multi-part */
797
798
799 /* preamble */
800
801 if (build_info->mm_data.mm_multipart.mm_preamble != NULL) {
802 r = mailmime_data_write(f, col,
803 build_info->mm_data.mm_multipart.mm_preamble, TRUE);
804 if (r != MAILIMF_NO_ERROR)
805 return r;
806
807 r = mailimf_string_write(f, col, "\r\n", 2);
808 if (r != MAILIMF_NO_ERROR)
809 return r;
810#if 0
811 * col = 0;
812#endif
813 }
814
815 /* sub-parts */
816
817 first = TRUE;
818
819 for(cur = clist_begin(build_info->mm_data.mm_multipart.mm_mp_list) ;
820 cur != NULL ; cur = clist_next(cur)) {
821 struct mailmime * subpart;
822
823 subpart = cur->data;
824
825 if (!first) {
826 r = mailimf_string_write(f, col, "\r\n", 2);
827 if (r != MAILIMF_NO_ERROR)
828 return r;
829#if 0
830 * col = 0;
831#endif
832 }
833 else {
834 first = FALSE;
835 }
836
837 r = mailimf_string_write(f, col, "--", 2);
838 if (r != MAILIMF_NO_ERROR)
839 return r;
840
841 r = mailimf_string_write(f, col, boundary, strlen(boundary));
842 if (r != MAILIMF_NO_ERROR)
843 return r;
844
845 r = mailimf_string_write(f, col, "\r\n", 2);
846 if (r != MAILIMF_NO_ERROR)
847 return r;
848#if 0
849 * col = 0;
850#endif
851
852 r = mailmime_sub_write(f, col, subpart);
853 if (r != MAILIMF_NO_ERROR)
854 return r;
855 }
856
857 r = mailimf_string_write(f, col, "\r\n", 2);
858 if (r != MAILIMF_NO_ERROR)
859 return r;
860#if 0
861 * col = 0;
862#endif
863
864 r = mailimf_string_write(f, col, "--", 2);
865 if (r != MAILIMF_NO_ERROR)
866 return r;
867
868 r = mailimf_string_write(f, col, boundary, strlen(boundary));
869 if (r != MAILIMF_NO_ERROR)
870 return r;
871
872 r = mailimf_string_write(f, col, "--", 2);
873 if (r != MAILIMF_NO_ERROR)
874 return r;
875
876
877 /* epilogue */
878
879 r = mailimf_string_write(f, col, "\r\n", 2);
880 if (r != MAILIMF_NO_ERROR)
881 return r;
882#if 0
883 * col = 0;
884#endif
885
886 if (build_info->mm_data.mm_multipart.mm_epilogue != NULL) {
887 r = mailmime_data_write(f, col,
888 build_info->mm_data.mm_multipart.mm_epilogue, TRUE);
889 if (r != MAILIMF_NO_ERROR)
890 return r;
891 }
892
893 break;
894
895 case MAILMIME_MESSAGE:
896
897 if (build_info->mm_data.mm_message.mm_fields != NULL) {
898 r = mailimf_fields_write(f, col,
899 build_info->mm_data.mm_message.mm_fields);
900 if (r != MAILIMF_NO_ERROR)
901 return r;
902 }
903
904 if (build_info->mm_mime_fields != NULL) {
905 r = mailmime_fields_write(f, col, build_info->mm_mime_fields);
906 if (r != MAILIMF_NO_ERROR)
907 return r;
908 }
909
910 /* encapsuled message */
911
912 if (build_info->mm_data.mm_message.mm_msg_mime != NULL) {
913 r = mailmime_sub_write(f, col,
914 build_info->mm_data.mm_message.mm_msg_mime);
915 if (r != MAILIMF_NO_ERROR)
916 return r;
917 }
918 break;
919
920 }
921
922 return MAILIMF_NO_ERROR;
923}
924
925
926static int mailmime_sub_write(FILE * f, int * col,
927 struct mailmime * build_info)
928{
929 int r;
930
931#if 0
932 * col = 0;
933#endif
934 /* MIME field - Content-Type */
935
936 if (build_info->mm_content_type != NULL) {
937 r = mailmime_content_write(f, col, build_info->mm_content_type);
938 if (r != MAILIMF_NO_ERROR)
939 return r;
940 }
941
942 /* other MIME fields */
943
944 if (build_info->mm_type != MAILMIME_MESSAGE) {
945 if (build_info->mm_mime_fields != NULL) {
946 r = mailmime_fields_write(f, col, build_info->mm_mime_fields);
947 if (r != MAILIMF_NO_ERROR)
948 return r;
949 }
950 }
951
952 r = mailimf_string_write(f, col, "\r\n", 2);
953 if (r != MAILIMF_NO_ERROR)
954 return r;
955#if 0
956 * col = 0;
957#endif
958
959 return mailmime_part_write(f, col, build_info);
960}
961
962int mailmime_write(FILE * f, int * col,
963 struct mailmime * build_info)
964{
965 if (build_info->mm_parent != NULL)
966 return mailmime_sub_write(f, col, build_info);
967 else
968 return mailmime_part_write(f, col, build_info);
969}
970
971
972int mailmime_data_write(FILE * f, int * col,
973 struct mailmime_data * data,
974 int istext)
975{
976 int fd;
977 int r;
978 char * text;
979 struct stat buf;
980 int res;
981
982 switch (data->dt_type) {
983 case MAILMIME_DATA_TEXT:
984
985 if (data->dt_encoded) {
986 r = mailimf_string_write(f, col,
987 data->dt_data.dt_text.dt_data,
988 data->dt_data.dt_text.dt_length);
989 if (r != MAILIMF_NO_ERROR)
990 return r;
991 }
992 else {
993 r = mailmime_text_content_write(f, col, data->dt_encoding, istext,
994 data->dt_data.dt_text.dt_data,
995 data->dt_data.dt_text.dt_length);
996 if (r != MAILIMF_NO_ERROR)
997 return r;
998 }
999
1000 break;
1001
1002 case MAILMIME_DATA_FILE:
1003 fd = open(data->dt_data.dt_filename, O_RDONLY);
1004 if (fd < 0) {
1005 res = MAILIMF_ERROR_FILE;
1006 goto err;
1007 }
1008
1009 r = fstat(fd, &buf);
1010 if (r < 0) {
1011 res = MAILIMF_ERROR_FILE;
1012 goto close;
1013 }
1014
1015 if (buf.st_size != 0) {
1016 text = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
1017 if (text == NULL) {
1018 res = MAILIMF_ERROR_FILE;
1019 goto close;
1020 }
1021
1022 if (data->dt_encoded) {
1023 r = mailimf_string_write(f, col, text, buf.st_size);
1024 if (r != MAILIMF_NO_ERROR) {
1025 res = r;
1026 goto unmap;
1027 }
1028 }
1029 else {
1030 r = mailmime_text_content_write(f, col, data->dt_encoding, istext,
1031 text, buf.st_size);
1032 if (r != MAILIMF_NO_ERROR) {
1033 res = r;
1034 goto unmap;
1035 }
1036 }
1037
1038 munmap(text, buf.st_size);
1039 }
1040 close(fd);
1041
1042 if (r != MAILIMF_NO_ERROR)
1043 return r;
1044
1045 break;
1046
1047 unmap:
1048 munmap(text, buf.st_size);
1049 close:
1050 close(fd);
1051 err:
1052 return res;
1053 }
1054
1055 return MAILIMF_NO_ERROR;
1056}
1057
1058static int mailmime_text_content_write(FILE * f, int * col, int encoding,
1059 int istext,
1060 const char * text, size_t size)
1061{
1062 switch (encoding) {
1063 case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
1064 return mailmime_quoted_printable_write(f, col, istext, text, size);
1065 break;
1066
1067 case MAILMIME_MECHANISM_BASE64:
1068 return mailmime_base64_write(f, col, text, size);
1069 break;
1070
1071 case MAILMIME_MECHANISM_7BIT:
1072 case MAILMIME_MECHANISM_8BIT:
1073 case MAILMIME_MECHANISM_BINARY:
1074 default:
1075 return mailimf_string_write(f, col, text, size);
1076 }
1077}
1078
1079
1080static const char base64_encoding[] =
1081"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1082
1083#define BASE64_MAX_COL 76
1084
1085int mailmime_base64_write(FILE * f, int * col,
1086 const char * text, size_t size)
1087{
1088 int a;
1089 int b;
1090 int c;
1091 size_t remains;
1092 const char * p;
1093 size_t count;
1094 char ogroup[4];
1095 int r;
1096
1097 remains = size;
1098 p = text;
1099
1100 while (remains > 0) {
1101 switch (remains) {
1102 case 1:
1103 a = (unsigned char) p[0];
1104 b = 0;
1105 c = 0;
1106 count = 1;
1107 break;
1108 case 2:
1109 a = (unsigned char) p[0];
1110 b = (unsigned char) p[1];
1111 c = 0;
1112 count = 2;
1113 break;
1114 default:
1115 a = (unsigned char) p[0];
1116 b = (unsigned char) p[1];
1117 c = (unsigned char) p[2];
1118 count = 3;
1119 break;
1120 }
1121
1122 ogroup[0]= base64_encoding[a >> 2];
1123 ogroup[1]= base64_encoding[((a & 3) << 4) | (b >> 4)];
1124 ogroup[2]= base64_encoding[((b & 0xF) << 2) | (c >> 6)];
1125 ogroup[3]= base64_encoding[c & 0x3F];
1126
1127 switch (count) {
1128 case 1:
1129 ogroup[2]= '=';
1130 ogroup[3]= '=';
1131 break;
1132 case 2:
1133 ogroup[3]= '=';
1134 break;
1135 }
1136
1137 if (* col + 4 > BASE64_MAX_COL) {
1138 r = mailimf_string_write(f, col, "\r\n", 2);
1139 if (r != MAILIMF_NO_ERROR)
1140 return r;
1141#if 0
1142 * col = 0;
1143#endif
1144 }
1145
1146 r = mailimf_string_write(f, col, ogroup, 4);
1147 if (r != MAILIMF_NO_ERROR)
1148 return r;
1149
1150 remains -= count;
1151 p += count;
1152 }
1153
1154 r = mailimf_string_write(f, col, "\r\n", 2);
1155
1156 return MAILIMF_NO_ERROR;
1157}
1158
1159#if 0
1160#define MAX_WRITE_SIZE 512
1161#endif
1162
1163enum {
1164 STATE_INIT,
1165 STATE_CR,
1166 STATE_SPACE,
1167 STATE_SPACE_CR,
1168};
1169
1170#if 0
1171static inline int write_try_buf(FILE * f, int * col,
1172 char ** pstart, size_t * plen)
1173{
1174 int r;
1175
1176 if (* plen >= MAX_WRITE_SIZE) {
1177 r = mailimf_string_write(f, col, * pstart, * plen);
1178 if (r != MAILIMF_NO_ERROR)
1179 return r;
1180 * plen = 0;
1181 }
1182
1183 return MAILIMF_NO_ERROR;
1184}
1185#endif
1186
1187static inline int write_remaining(FILE * f, int * col,
1188 const char ** pstart, size_t * plen)
1189{
1190 int r;
1191
1192 if (* plen > 0) {
1193 r = mailimf_string_write(f, col, * pstart, * plen);
1194 if (r != MAILIMF_NO_ERROR)
1195 return r;
1196 * plen = 0;
1197 }
1198
1199 return MAILIMF_NO_ERROR;
1200}
1201
1202
1203
1204#define QP_MAX_COL 72
1205
1206int mailmime_quoted_printable_write(FILE * f, int * col, int istext,
1207 const char * text, size_t size)
1208{
1209 size_t i;
1210 const char * start;
1211 size_t len;
1212 char hexstr[6];
1213 int r;
1214 int state;
1215
1216 start = text;
1217 len = 0;
1218 state = STATE_INIT;
1219
1220 i = 0;
1221 while (i < size) {
1222 unsigned char ch;
1223
1224 if (* col + len > QP_MAX_COL) {
1225 r = write_remaining(f, col, &start, &len);
1226 if (r != MAILIMF_NO_ERROR)
1227 return r;
1228 start = text + i;
1229
1230 r = mailimf_string_write(f, col, "=\r\n", 3);
1231 if (r != MAILIMF_NO_ERROR)
1232 return r;
1233 }
1234
1235 ch = text[i];
1236
1237 switch (state) {
1238
1239 case STATE_INIT:
1240 switch (ch) {
1241 case ' ':
1242 case '\t':
1243 state = STATE_SPACE;
1244 break;
1245
1246 case '\r':
1247 state = STATE_CR;
1248 break;
1249
1250 case '!':
1251 case '"':
1252 case '#':
1253 case '$':
1254 case '@':
1255 case '[':
1256 case '\\':
1257 case ']':
1258 case '^':
1259 case '`':
1260 case '{':
1261 case '|':
1262 case '}':
1263 case '~':
1264 case '=':
1265 case '?':
1266 case '_':
1267 case 'F': /* there is no more 'From' at the beginning of a line */
1268 r = write_remaining(f, col, &start, &len);
1269 if (r != MAILIMF_NO_ERROR)
1270 return r;
1271 start = text + i + 1;
1272
1273 snprintf(hexstr, 6, "=%02X", ch);
1274
1275 r = mailimf_string_write(f, col, hexstr, 3);
1276 if (r != MAILIMF_NO_ERROR)
1277 return r;
1278 break;
1279
1280 default:
1281 if (istext && (ch == '\n')) {
1282 r = write_remaining(f, col, &start, &len);
1283 if (r != MAILIMF_NO_ERROR)
1284 return r;
1285 start = text + i + 1;
1286
1287 r = mailimf_string_write(f, col, "\r\n", 2);
1288 if (r != MAILIMF_NO_ERROR)
1289 return r;
1290 break;
1291 }
1292 else {
1293 if (((ch >= 33) && (ch <= 60)) || ((ch >= 62) && (ch <= 126))) {
1294 len ++;
1295 }
1296 else {
1297 r = write_remaining(f, col, &start, &len);
1298 if (r != MAILIMF_NO_ERROR)
1299 return r;
1300 start = text + i + 1;
1301
1302 snprintf(hexstr, 6, "=%02X", ch);
1303
1304 r = mailimf_string_write(f, col, hexstr, 3);
1305 if (r != MAILIMF_NO_ERROR)
1306 return r;
1307 }
1308 }
1309
1310 break;
1311 }
1312
1313 i ++;
1314 break;
1315
1316 case STATE_CR:
1317 switch (ch) {
1318 case '\n':
1319 r = write_remaining(f, col, &start, &len);
1320 if (r != MAILIMF_NO_ERROR)
1321 return r;
1322 start = text + i + 1;
1323 r = mailimf_string_write(f, col, "\r\n", 2);
1324 if (r != MAILIMF_NO_ERROR)
1325 return r;
1326 i ++;
1327 state = STATE_INIT;
1328 break;
1329
1330 default:
1331 r = write_remaining(f, col, &start, &len);
1332 if (r != MAILIMF_NO_ERROR)
1333 return r;
1334 start = text + i;
1335 snprintf(hexstr, 6, "=%02X", '\r');
1336 r = mailimf_string_write(f, col, hexstr, 3);
1337 if (r != MAILIMF_NO_ERROR)
1338 return r;
1339 state = STATE_INIT;
1340 break;
1341 }
1342 break;
1343
1344 case STATE_SPACE:
1345 switch (ch) {
1346 case '\r':
1347 state = STATE_SPACE_CR;
1348 i ++;
1349 break;
1350
1351 case '\n':
1352 r = write_remaining(f, col, &start, &len);
1353 if (r != MAILIMF_NO_ERROR)
1354 return r;
1355 start = text + i + 1;
1356 snprintf(hexstr, 6, "=%02X\r\n", text[i - 1]);
1357 r = mailimf_string_write(f, col, hexstr, strlen(hexstr));
1358 if (r != MAILIMF_NO_ERROR)
1359 return r;
1360 state = STATE_INIT;
1361 i ++;
1362 break;
1363
1364 case ' ':
1365 case '\t':
1366 len ++;
1367 i ++;
1368 break;
1369
1370 default:
1371#if 0
1372 len += 2;
1373 state = STATE_INIT;
1374 i ++;
1375#endif
1376 len ++;
1377 state = STATE_INIT;
1378 break;
1379 }
1380
1381 break;
1382
1383 case STATE_SPACE_CR:
1384 switch (ch) {
1385 case '\n':
1386 r = write_remaining(f, col, &start, &len);
1387 if (r != MAILIMF_NO_ERROR)
1388 return r;
1389 start = text + i + 1;
1390 snprintf(hexstr, 6, "=%02X\r\n", text[i - 2]);
1391 r = mailimf_string_write(f, col, hexstr, strlen(hexstr));
1392 if (r != MAILIMF_NO_ERROR)
1393 return r;
1394 state = STATE_INIT;
1395 i ++;
1396 break;
1397
1398 default:
1399 r = write_remaining(f, col, &start, &len);
1400 if (r != MAILIMF_NO_ERROR)
1401 return r;
1402 start = text + i + 1;
1403 snprintf(hexstr, 6, "%c=%02X", text[i - 2], '\r');
1404 r = mailimf_string_write(f, col, hexstr, strlen(hexstr));
1405 if (r != MAILIMF_NO_ERROR)
1406 return r;
1407 state = STATE_INIT;
1408 break;
1409 }
1410
1411 break;
1412 }
1413 }
1414
1415 return MAILIMF_NO_ERROR;
1416}
diff --git a/kmicromail/libetpan/mime/mailmime_write.h b/kmicromail/libetpan/mime/mailmime_write.h
new file mode 100644
index 0000000..96f8777
--- a/dev/null
+++ b/kmicromail/libetpan/mime/mailmime_write.h
@@ -0,0 +1,73 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILMIME_WRITE_H
37
38#define MAILMIME_WRITE_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailmime_types.h>
45#include <stdio.h>
46
47int mailmime_fields_write(FILE * f, int * col,
48 struct mailmime_fields * fields);
49
50int mailmime_content_write(FILE * f, int * col,
51 struct mailmime_content * content);
52
53int mailmime_content_type_write(FILE * f, int * col,
54 struct mailmime_content * content);
55
56int mailmime_write(FILE * f, int * col,
57 struct mailmime * build_info);
58
59int mailmime_quoted_printable_write(FILE * f, int * col, int istext,
60 const char * text, size_t size);
61
62int mailmime_base64_write(FILE * f, int * col,
63 const char * text, size_t size);
64
65int mailmime_data_write(FILE * f, int * col,
66 struct mailmime_data * data,
67 int istext);
68
69#ifdef __cplusplus
70}
71#endif
72
73#endif
diff --git a/kmicromail/libetpan/nntp/.libs/libnewsnntp.a b/kmicromail/libetpan/nntp/.libs/libnewsnntp.a
new file mode 100644
index 0000000..7c524b7
--- a/dev/null
+++ b/kmicromail/libetpan/nntp/.libs/libnewsnntp.a
Binary files differ
diff --git a/kmicromail/libetpan/nntp/newsnntp.c b/kmicromail/libetpan/nntp/newsnntp.c
new file mode 100644
index 0000000..0806290
--- a/dev/null
+++ b/kmicromail/libetpan/nntp/newsnntp.c
@@ -0,0 +1,2486 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "newsnntp.h"
37
38
39#include <unistd.h>
40#include <stdio.h>
41#include <netinet/in.h>
42#include <netdb.h>
43#include <string.h>
44#include <stdlib.h>
45#include <time.h>
46
47#include "connect.h"
48#include "mail.h"
49#include "clist.h"
50
51/*
52 NNTP Protocol
53
54 RFC 977
55 RFC 2980
56
57 TODO :
58
59 XPAT header range|<message-id> pat [pat...]
60
61
62 */
63
64
65
66
67#define NNTP_STRING_SIZE 513
68
69
70
71static char * read_line(newsnntp * f);
72static char * read_multiline(newsnntp * f, size_t size,
73 MMAPString * multiline_buffer);
74static int parse_response(newsnntp * f, char * response);
75
76static int send_command(newsnntp * f, char * command);
77
78newsnntp * newsnntp_new(size_t progr_rate, progress_function * progr_fun)
79{
80 newsnntp * f;
81
82 f = malloc(sizeof(* f));
83 if (f == NULL)
84 goto err;
85
86 f->nntp_stream = NULL;
87 f->nntp_readonly = FALSE;
88
89 f->nntp_progr_rate = progr_rate;
90 f->nntp_progr_fun = progr_fun;
91
92 f->nntp_stream_buffer = mmap_string_new("");
93 if (f->nntp_stream_buffer == NULL)
94 goto free_f;
95
96 f->nntp_response_buffer = mmap_string_new("");
97 if (f->nntp_response_buffer == NULL)
98 goto free_stream_buffer;
99
100 return f;
101
102 free_stream_buffer:
103 mmap_string_free(f->nntp_stream_buffer);
104 free_f:
105 free(f);
106 err:
107 return NULL;
108}
109
110void newsnntp_free(newsnntp * f)
111{
112 if (f->nntp_stream)
113 newsnntp_quit(f);
114
115 mmap_string_free(f->nntp_response_buffer);
116 mmap_string_free(f->nntp_stream_buffer);
117
118 free(f);
119}
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136int newsnntp_quit(newsnntp * f)
137{
138 char command[NNTP_STRING_SIZE];
139 char * response;
140 int r;
141 int res;
142
143 if (f->nntp_stream == NULL)
144 return NEWSNNTP_ERROR_BAD_STATE;
145
146 snprintf(command, NNTP_STRING_SIZE, "QUIT\r\n");
147 r = send_command(f, command);
148 if (r == -1) {
149 res = NEWSNNTP_ERROR_STREAM;
150 goto close;
151 }
152
153 response = read_line(f);
154 if (response == NULL) {
155 res = NEWSNNTP_ERROR_STREAM;
156 goto close;
157 }
158
159 parse_response(f, response);
160
161 res = NEWSNNTP_NO_ERROR;
162
163 close:
164
165 mailstream_close(f->nntp_stream);
166
167 f->nntp_stream = NULL;
168
169 return res;
170}
171
172int newsnntp_connect(newsnntp * f, mailstream * s)
173{
174 char * response;
175 int r;
176
177 if (f->nntp_stream != NULL)
178 return NEWSNNTP_ERROR_BAD_STATE;
179
180 f->nntp_stream = s;
181
182 response = read_line(f);
183 if (response == NULL)
184 return NEWSNNTP_ERROR_STREAM;
185
186 r = parse_response(f, response);
187
188 switch (r) {
189 case 200:
190 f->nntp_readonly = FALSE;
191 return NEWSNNTP_NO_ERROR;
192
193 case 201:
194 f->nntp_readonly = TRUE;
195 return NEWSNNTP_NO_ERROR;
196
197 default:
198 f->nntp_stream = NULL;
199 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
200 }
201}
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222/*
223static struct newsnntp_xover_resp_item * get_xover_info(newsnntp * f,
224 guint32 article);
225*/
226
227static void newsnntp_multiline_response_free(char * str)
228{
229 mmap_string_unref(str);
230}
231
232void newsnntp_head_free(char * str)
233{
234 newsnntp_multiline_response_free(str);
235}
236
237void newsnntp_article_free(char * str)
238{
239 newsnntp_multiline_response_free(str);
240}
241
242void newsnntp_body_free(char * str)
243{
244 newsnntp_multiline_response_free(str);
245}
246
247/* ******************** HEADER ******************************** */
248
249/*
250 message content in (* result) is still there until the
251 next retrieve or top operation on the mailpop3 structure
252*/
253
254static int newsnntp_get_content(newsnntp * f, char ** result,
255 size_t * result_len)
256{
257 int r;
258 char * response;
259 MMAPString * buffer;
260 char * result_multiline;
261
262 response = read_line(f);
263 if (response == NULL)
264 return NEWSNNTP_ERROR_STREAM;
265
266 r = parse_response(f, response);
267
268 switch (r) {
269 case 480:
270 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
271
272 case 381:
273 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
274
275 case 220:
276 case 221:
277 case 222:
278 case 223:
279 buffer = mmap_string_new("");
280 if (buffer == NULL)
281 return NEWSNNTP_ERROR_MEMORY;
282
283 result_multiline = read_multiline(f, 0, buffer);
284 if (result_multiline == NULL) {
285 mmap_string_free(buffer);
286 return NEWSNNTP_ERROR_MEMORY;
287 }
288 else {
289 r = mmap_string_ref(buffer);
290 if (r < 0) {
291 mmap_string_free(buffer);
292 return NEWSNNTP_ERROR_MEMORY;
293 }
294
295 * result = result_multiline;
296 * result_len = buffer->len;
297 return NEWSNNTP_NO_ERROR;
298 }
299
300 case 412:
301 return NEWSNNTP_ERROR_NO_NEWSGROUP_SELECTED;
302
303 case 420:
304 return NEWSNNTP_ERROR_NO_ARTICLE_SELECTED;
305
306 case 423:
307 return NEWSNNTP_ERROR_INVALID_ARTICLE_NUMBER;
308
309 case 430:
310 return NEWSNNTP_ERROR_ARTICLE_NOT_FOUND;
311
312 default:
313 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
314 }
315}
316
317int newsnntp_head(newsnntp * f, uint32_t index, char ** result,
318 size_t * result_len)
319{
320 char command[NNTP_STRING_SIZE];
321 int r;
322
323 snprintf(command, NNTP_STRING_SIZE, "HEAD %i\r\n", index);
324 r = send_command(f, command);
325 if (r == -1)
326 return NEWSNNTP_ERROR_STREAM;
327
328 return newsnntp_get_content(f, result, result_len);
329}
330
331/* ******************** ARTICLE ******************************** */
332
333int newsnntp_article(newsnntp * f, uint32_t index, char ** result,
334 size_t * result_len)
335{
336 char command[NNTP_STRING_SIZE];
337 int r;
338
339 snprintf(command, NNTP_STRING_SIZE, "ARTICLE %i\r\n", index);
340 r = send_command(f, command);
341 if (r == -1)
342 return NEWSNNTP_ERROR_STREAM;
343
344 return newsnntp_get_content(f, result, result_len);
345}
346
347/* ******************** BODY ******************************** */
348
349int newsnntp_body(newsnntp * f, uint32_t index, char ** result,
350 size_t * result_len)
351{
352 char command[NNTP_STRING_SIZE];
353 int r;
354
355 snprintf(command, NNTP_STRING_SIZE, "BODY %i\r\n", index);
356 r = send_command(f, command);
357 if (r == -1)
358 return NEWSNNTP_ERROR_STREAM;
359
360 return newsnntp_get_content(f, result, result_len);
361}
362
363/* ******************** GROUP ******************************** */
364
365static struct newsnntp_group_info *
366group_info_init(char * name, uint32_t first, uint32_t last, uint32_t count,
367 char type)
368{
369 struct newsnntp_group_info * n;
370
371 n = malloc(sizeof(* n));
372
373 if (n == NULL)
374 return NULL;
375
376 n->grp_name = strdup(name);
377 if (n->grp_name == NULL) {
378 free(n);
379 return NULL;
380 }
381
382 n->grp_first = first;
383 n->grp_last = last;
384 n->grp_count = count;
385 n->grp_type = type;
386
387 return n;
388}
389
390static void group_info_free(struct newsnntp_group_info * n)
391{
392 if (n->grp_name)
393 free(n->grp_name);
394 free(n);
395}
396
397static void group_info_list_free(clist * l)
398{
399 clist_foreach(l, (clist_func) group_info_free, NULL);
400 clist_free(l);
401}
402
403static int parse_group_info(char * response,
404 struct newsnntp_group_info ** info);
405
406int newsnntp_group(newsnntp * f, const char * groupname,
407 struct newsnntp_group_info ** info)
408{
409 char command[NNTP_STRING_SIZE];
410 int r;
411 char * response;
412
413 snprintf(command, NNTP_STRING_SIZE, "GROUP %s\r\n", groupname);
414 r = send_command(f, command);
415 if (r == -1)
416 return NEWSNNTP_ERROR_STREAM;
417
418 response = read_line(f);
419 if (response == NULL)
420 return NEWSNNTP_ERROR_STREAM;
421
422 r = parse_response(f, response);
423
424 switch (r) {
425 case 480:
426 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
427
428 case 381:
429 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
430
431 case 211:
432 if (!parse_group_info(f->nntp_response, info))
433 return NEWSNNTP_ERROR_INVALID_RESPONSE;
434 return NEWSNNTP_NO_ERROR;
435
436 case 411:
437 return NEWSNNTP_ERROR_NO_SUCH_NEWS_GROUP;
438
439 default:
440 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
441 }
442}
443
444void newsnntp_group_free(struct newsnntp_group_info * info)
445{
446 group_info_free(info);
447}
448
449/* ******************** LIST ******************************** */
450
451static clist * read_groups_list(newsnntp * f);
452
453int newsnntp_list(newsnntp * f, clist ** result)
454{
455 char command[NNTP_STRING_SIZE];
456 int r;
457 char * response;
458
459 snprintf(command, NNTP_STRING_SIZE, "LIST\r\n");
460 r = send_command(f, command);
461 if (r == -1)
462 return NEWSNNTP_ERROR_STREAM;
463
464 response = read_line(f);
465 if (response == NULL)
466 return NEWSNNTP_ERROR_STREAM;
467
468 r = parse_response(f, response);
469
470 switch (r) {
471 case 480:
472 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
473
474 case 381:
475 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
476
477 case 215:
478 * result = read_groups_list(f);
479 return NEWSNNTP_NO_ERROR;
480
481 default:
482 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
483 }
484}
485
486void newsnntp_list_free(clist * l)
487{
488 group_info_list_free(l);
489}
490
491/* ******************** POST ******************************** */
492
493static void send_data(newsnntp * f, const char * message, uint32_t size)
494{
495 mailstream_send_data(f->nntp_stream, message, size,
496 f->nntp_progr_rate, f->nntp_progr_fun);
497}
498
499
500int newsnntp_post(newsnntp * f, const char * message, size_t size)
501{
502 char command[NNTP_STRING_SIZE];
503 int r;
504 char * response;
505
506 snprintf(command, NNTP_STRING_SIZE, "POST\r\n");
507 r = send_command(f, command);
508 if (r == -1)
509 return NEWSNNTP_ERROR_STREAM;
510
511 response = read_line(f);
512 if (response == NULL)
513 return NEWSNNTP_ERROR_STREAM;
514
515 r = parse_response(f, response);
516
517 switch (r) {
518 case 480:
519 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
520
521 case 381:
522 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
523
524 case 340:
525 break;
526
527 case 440:
528 return NEWSNNTP_ERROR_POSTING_NOT_ALLOWED;
529
530 default:
531 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
532 }
533
534 send_data(f, message, size);
535
536 response = read_line(f);
537 if (response == NULL)
538 return NEWSNNTP_ERROR_STREAM;
539
540 r = parse_response(f, response);
541
542 switch (r) {
543 case 480:
544 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
545
546 case 381:
547 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
548
549 case 240:
550 return NEWSNNTP_NO_ERROR;
551 return 1;
552
553 case 441:
554 return NEWSNNTP_ERROR_POSTING_FAILED;
555
556 default:
557 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
558 }
559}
560
561
562/* ******************** AUTHINFO ******************************** */
563
564int newsnntp_authinfo_username(newsnntp * f, const char * username)
565{
566 char command[NNTP_STRING_SIZE];
567 int r;
568 char * response;
569
570 snprintf(command, NNTP_STRING_SIZE, "AUTHINFO USER %s\r\n", username);
571 r = send_command(f, command);
572 if (r == -1)
573 return NEWSNNTP_ERROR_STREAM;
574
575 response = read_line(f);
576 if (response == NULL)
577 return NEWSNNTP_ERROR_STREAM;
578
579 r = parse_response(f, response);
580
581 switch (r) {
582 case 480:
583 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
584
585 case 482:
586 return NEWSNNTP_ERROR_AUTHENTICATION_REJECTED;
587
588 case 381:
589 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
590
591 case 281:
592 return NEWSNNTP_NO_ERROR;
593
594 default:
595 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
596 }
597}
598
599int newsnntp_authinfo_password(newsnntp * f, const char * password)
600{
601 char command[NNTP_STRING_SIZE];
602 int r;
603 char * response;
604
605 snprintf(command, NNTP_STRING_SIZE, "AUTHINFO PASS %s\r\n", password);
606 r = send_command(f, command);
607 if (r == -1)
608 return NEWSNNTP_ERROR_STREAM;
609
610 response = read_line(f);
611 if (response == NULL)
612 return NEWSNNTP_ERROR_STREAM;
613
614 r = parse_response(f, response);
615
616 switch (r) {
617 case 480:
618 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
619
620 case 482:
621 return NEWSNNTP_ERROR_AUTHENTICATION_REJECTED;
622
623 case 381:
624 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
625
626 case 281:
627 return NEWSNNTP_NO_ERROR;
628
629 default:
630 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
631 }
632}
633
634/* ******************** LIST OVERVIEW.FMT ******************************** */
635
636static clist * read_headers_list(newsnntp * f);
637
638static void headers_list_free(clist * l)
639{
640 clist_foreach(l, (clist_func) free, NULL);
641 clist_free(l);
642}
643
644int newsnntp_list_overview_fmt(newsnntp * f, clist ** result)
645{
646 char command[NNTP_STRING_SIZE];
647 int r;
648 char * response;
649
650 snprintf(command, NNTP_STRING_SIZE, "LIST OVERVIEW.FMT\r\n");
651 r = send_command(f, command);
652 if (r == -1)
653 return NEWSNNTP_ERROR_STREAM;
654
655 response = read_line(f);
656 if (response == NULL)
657 return NEWSNNTP_ERROR_STREAM;
658
659 r = parse_response(f, response);
660
661 switch (r) {
662 case 480:
663 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
664
665 case 381:
666 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
667
668 case 215:
669 * result = read_headers_list(f);
670 return NEWSNNTP_NO_ERROR;
671
672 case 503:
673 return NEWSNNTP_ERROR_PROGRAM_ERROR;
674
675 default:
676 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
677 }
678}
679
680void newsnntp_list_overview_fmt_free(clist * l)
681{
682 headers_list_free(l);
683}
684
685
686
687
688
689
690/* ******************** LIST ACTIVE ******************************** */
691
692int newsnntp_list_active(newsnntp * f, const char * wildcard, clist ** result)
693{
694 char command[NNTP_STRING_SIZE];
695 int r;
696 char * response;
697
698 if (wildcard != NULL)
699 snprintf(command, NNTP_STRING_SIZE, "LIST ACTIVE %s\r\n", wildcard);
700 else
701 snprintf(command, NNTP_STRING_SIZE, "LIST ACTIVE\r\n");
702 r = send_command(f, command);
703 if (r == -1)
704 return NEWSNNTP_ERROR_STREAM;
705
706 response = read_line(f);
707 if (response == NULL)
708 return NEWSNNTP_ERROR_STREAM;
709
710 r = parse_response(f, response);
711
712 switch (r) {
713 case 480:
714 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
715
716 case 381:
717 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
718
719 case 215:
720 * result = read_groups_list(f);
721 return NEWSNNTP_NO_ERROR;
722
723 default:
724 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
725 }
726}
727
728void newsnntp_list_active_free(clist * l)
729{
730 group_info_list_free(l);
731}
732
733
734
735
736
737
738/* ******************** LIST ACTIVE.TIMES ******************************** */
739
740static struct newsnntp_group_time *
741group_time_new(char * group_name, time_t date, char * email)
742{
743 struct newsnntp_group_time * n;
744
745 n = malloc(sizeof(* n));
746
747 if (n == NULL)
748 return NULL;
749
750 n->grp_name = strdup(group_name);
751 if (n->grp_name == NULL) {
752 free(n);
753 return NULL;
754 }
755
756 n->grp_email = strdup(email);
757 if (n->grp_email == NULL) {
758 free(n->grp_name);
759 free(n);
760 return NULL;
761 }
762
763 n->grp_date = date;
764
765 return n;
766}
767
768static void group_time_free(struct newsnntp_group_time * n)
769{
770 if (n->grp_name)
771 free(n->grp_name);
772 if (n->grp_email)
773 free(n->grp_email);
774 free(n);
775}
776
777static void group_time_list_free(clist * l)
778{
779 clist_foreach(l, (clist_func) group_time_free, NULL);
780 clist_free(l);
781}
782
783
784
785
786
787
788
789static clist * read_group_time_list(newsnntp * f);
790
791
792int newsnntp_list_active_times(newsnntp * f, clist ** result)
793{
794 char command[NNTP_STRING_SIZE];
795 int r;
796 char * response;
797
798 snprintf(command, NNTP_STRING_SIZE, "LIST ACTIVE.TIMES\r\n");
799 r = send_command(f, command);
800 if (r == -1)
801 return NEWSNNTP_ERROR_STREAM;
802
803 response = read_line(f);
804 if (response == NULL)
805 return NEWSNNTP_ERROR_STREAM;
806
807 r = parse_response(f, response);
808
809 switch (r) {
810 case 480:
811 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
812
813 case 381:
814 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
815
816 case 215:
817 * result = read_group_time_list(f);
818 return NEWSNNTP_NO_ERROR;
819
820 case 503:
821 return NEWSNNTP_ERROR_PROGRAM_ERROR;
822
823 default:
824 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
825 }
826}
827
828void newsnntp_list_active_times_free(clist * l)
829{
830 group_time_list_free(l);
831}
832
833
834
835
836
837
838
839
840/* ********************** LIST DISTRIBUTION ***************************** */
841
842static struct newsnntp_distrib_value_meaning *
843distrib_value_meaning_new(char * value, char * meaning)
844{
845 struct newsnntp_distrib_value_meaning * n;
846
847 n = malloc(sizeof(* n));
848
849 if (n == NULL)
850 return NULL;
851
852 n->dst_value = strdup(value);
853 if (n->dst_value == NULL) {
854 free(n);
855 return NULL;
856 }
857
858 n->dst_meaning = strdup(meaning);
859 if (n->dst_meaning == NULL) {
860 free(n->dst_value);
861 free(n);
862 return NULL;
863 }
864
865 return n;
866}
867
868
869static void
870distrib_value_meaning_free(struct newsnntp_distrib_value_meaning * n)
871{
872 if (n->dst_value)
873 free(n->dst_value);
874 if (n->dst_meaning)
875 free(n->dst_meaning);
876 free(n);
877}
878
879static void distrib_value_meaning_list_free(clist * l)
880{
881 clist_foreach(l, (clist_func) distrib_value_meaning_free, NULL);
882 clist_free(l);
883}
884
885static clist * read_distrib_value_meaning_list(newsnntp * f);
886
887
888int newsnntp_list_distribution(newsnntp * f, clist ** result)
889{
890 char command[NNTP_STRING_SIZE];
891 int r;
892 char * response;
893
894 snprintf(command, NNTP_STRING_SIZE, "LIST DISTRIBUTION\r\n");
895 r = send_command(f, command);
896 if (r == -1)
897 return NEWSNNTP_ERROR_STREAM;
898
899 response = read_line(f);
900 if (response == NULL)
901 return NEWSNNTP_ERROR_STREAM;
902
903 r = parse_response(f, response);
904
905 switch (r) {
906 case 480:
907 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
908
909 case 381:
910 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
911
912 case 215:
913 * result = read_distrib_value_meaning_list(f);
914 return NEWSNNTP_NO_ERROR;
915
916 case 503:
917 return NEWSNNTP_ERROR_PROGRAM_ERROR;
918
919 default:
920 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
921 }
922}
923
924
925void newsnntp_list_distribution_free(clist * l)
926{
927 distrib_value_meaning_list_free(l);
928}
929
930
931
932
933
934
935
936
937
938
939
940/* ********************** LIST DISTRIB.PATS ***************************** */
941
942static struct newsnntp_distrib_default_value *
943distrib_default_value_new(uint32_t weight, char * group_pattern, char * value)
944{
945 struct newsnntp_distrib_default_value * n;
946
947 n = malloc(sizeof(* n));
948 if (n == NULL)
949 return NULL;
950
951 n->dst_group_pattern = strdup(group_pattern);
952 if (n->dst_group_pattern == NULL) {
953 free(n);
954 return NULL;
955 }
956
957 n->dst_value = strdup(value);
958 if (n->dst_value == NULL) {
959 free(n->dst_group_pattern);
960 free(n);
961 return NULL;
962 }
963
964 n->dst_weight = weight;
965
966 return n;
967}
968
969static void
970distrib_default_value_free(struct newsnntp_distrib_default_value * n)
971{
972 if (n->dst_group_pattern)
973 free(n->dst_group_pattern);
974 if (n->dst_value)
975 free(n->dst_value);
976 free(n);
977}
978
979static void distrib_default_value_list_free(clist * l)
980{
981 clist_foreach(l, (clist_func) distrib_default_value_free, NULL);
982 clist_free(l);
983}
984
985static clist * read_distrib_default_value_list(newsnntp * f);
986
987int newsnntp_list_distrib_pats(newsnntp * f, clist ** result)
988{
989 char command[NNTP_STRING_SIZE];
990 int r;
991 char * response;
992
993 snprintf(command, NNTP_STRING_SIZE, "LIST DISTRIB.PATS\r\n");
994 r = send_command(f, command);
995 if (r == -1)
996 return NEWSNNTP_ERROR_STREAM;
997
998 response = read_line(f);
999 if (response == NULL)
1000 return NEWSNNTP_ERROR_STREAM;
1001
1002 r = parse_response(f, response);
1003
1004 switch (r) {
1005 case 480:
1006 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
1007
1008 case 381:
1009 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
1010
1011 case 215:
1012 * result = read_distrib_default_value_list(f);
1013 return NEWSNNTP_NO_ERROR;
1014
1015 case 503:
1016 return NEWSNNTP_ERROR_PROGRAM_ERROR;
1017
1018 default:
1019 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
1020 }
1021}
1022
1023void newsnntp_list_distrib_pats_free(clist * l)
1024{
1025 distrib_default_value_list_free(l);
1026}
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039/* ********************** LIST NEWSGROUPS ***************************** */
1040
1041static struct newsnntp_group_description *
1042group_description_new(char * group_name, char * description)
1043{
1044 struct newsnntp_group_description * n;
1045
1046 n = malloc(sizeof(* n));
1047 if (n == NULL)
1048 return NULL;
1049
1050 n->grp_name = strdup(group_name);
1051 if (n->grp_name == NULL) {
1052 free(n);
1053 return NULL;
1054 }
1055
1056 n->grp_description = strdup(description);
1057 if (n->grp_description == NULL) {
1058 free(n->grp_name);
1059 free(n);
1060 return NULL;
1061 }
1062
1063 return n;
1064}
1065
1066static void group_description_free(struct newsnntp_group_description * n)
1067{
1068 if (n->grp_name)
1069 free(n->grp_name);
1070 if (n->grp_description)
1071 free(n->grp_description);
1072 free(n);
1073}
1074
1075static void group_description_list_free(clist * l)
1076{
1077 clist_foreach(l, (clist_func) group_description_free, NULL);
1078 clist_free(l);
1079}
1080
1081static clist * read_group_description_list(newsnntp * f);
1082
1083int newsnntp_list_newsgroups(newsnntp * f, const char * pattern,
1084 clist ** result)
1085{
1086 char command[NNTP_STRING_SIZE];
1087 int r;
1088 char * response;
1089
1090 if (pattern)
1091 snprintf(command, NNTP_STRING_SIZE, "LIST NEWSGROUPS %s\r\n", pattern);
1092 else
1093 snprintf(command, NNTP_STRING_SIZE, "LIST NEWSGROUPS\r\n");
1094
1095 r = send_command(f, command);
1096 if (r == -1)
1097 return NEWSNNTP_ERROR_STREAM;
1098
1099 response = read_line(f);
1100 if (response == NULL)
1101 return NEWSNNTP_ERROR_STREAM;
1102
1103 r = parse_response(f, response);
1104
1105 switch (r) {
1106 case 480:
1107 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
1108
1109 case 381:
1110 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
1111
1112 case 215:
1113 * result = read_group_description_list(f);
1114 return NEWSNNTP_NO_ERROR;
1115
1116 case 503:
1117 return NEWSNNTP_ERROR_PROGRAM_ERROR;
1118
1119 default:
1120 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
1121 }
1122}
1123
1124void newsnntp_list_newsgroups_free(clist * l)
1125{
1126 group_description_list_free(l);
1127}
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140/* ******************** LIST SUBSCRIPTIONS ******************************** */
1141
1142static void subscriptions_list_free(clist * l)
1143{
1144 clist_foreach(l, (clist_func) free, NULL);
1145 clist_free(l);
1146}
1147
1148static clist * read_subscriptions_list(newsnntp * f);
1149
1150int newsnntp_list_subscriptions(newsnntp * f, clist ** result)
1151{
1152 char command[NNTP_STRING_SIZE];
1153 int r;
1154 char * response;
1155
1156 snprintf(command, NNTP_STRING_SIZE, "LIST SUBSCRIPTIONS\r\n");
1157 r = send_command(f, command);
1158 if (r == -1)
1159 return NEWSNNTP_ERROR_STREAM;
1160
1161 response = read_line(f);
1162 if (response == NULL)
1163 return NEWSNNTP_ERROR_STREAM;
1164
1165 r = parse_response(f, response);
1166
1167 switch (r) {
1168 case 480:
1169 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
1170
1171 case 381:
1172 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
1173
1174 case 215:
1175 * result = read_subscriptions_list(f);
1176 return NEWSNNTP_NO_ERROR;
1177
1178 case 503:
1179 return NEWSNNTP_ERROR_PROGRAM_ERROR;
1180
1181 default:
1182 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
1183 }
1184}
1185
1186void newsnntp_list_subscriptions_free(clist * l)
1187{
1188 subscriptions_list_free(l);
1189}
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202/* ******************** LISTGROUP ******************************** */
1203
1204static void articles_list_free(clist * l)
1205{
1206 clist_foreach(l, (clist_func) free, NULL);
1207 clist_free(l);
1208}
1209
1210static clist * read_articles_list(newsnntp * f);
1211
1212int newsnntp_listgroup(newsnntp * f, const char * group_name,
1213 clist ** result)
1214{
1215 char command[NNTP_STRING_SIZE];
1216 int r;
1217 char * response;
1218
1219 if (group_name)
1220 snprintf(command, NNTP_STRING_SIZE, "LISTGROUP %s\r\n", group_name);
1221 else
1222 snprintf(command, NNTP_STRING_SIZE, "LISTGROUP\r\n");
1223 r = send_command(f, command);
1224 if (r == -1)
1225 return NEWSNNTP_ERROR_STREAM;
1226
1227 response = read_line(f);
1228 if (response == NULL)
1229 return NEWSNNTP_ERROR_STREAM;
1230
1231 r = parse_response(f, response);
1232
1233 switch (r) {
1234 case 480:
1235 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
1236
1237 case 381:
1238 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
1239
1240 case 211:
1241 * result = read_articles_list(f);
1242 return NEWSNNTP_NO_ERROR;
1243
1244 case 412:
1245 return NEWSNNTP_ERROR_NO_NEWSGROUP_SELECTED;
1246
1247 case 502:
1248 return NEWSNNTP_ERROR_NO_PERMISSION;
1249
1250 default:
1251 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
1252 }
1253}
1254
1255void newsnntp_listgroup_free(clist * l)
1256{
1257 articles_list_free(l);
1258}
1259
1260
1261
1262
1263
1264
1265
1266/* ********************** MODE READER ***************************** */
1267
1268int newsnntp_mode_reader(newsnntp * f)
1269{
1270 char command[NNTP_STRING_SIZE];
1271 char * response;
1272 int r;
1273
1274 snprintf(command, NNTP_STRING_SIZE, "MODE READER\r\n");
1275
1276 r = send_command(f, command);
1277 if (r == -1)
1278 return NEWSNNTP_ERROR_STREAM;
1279
1280 response = read_line(f);
1281 if (response == NULL)
1282 return NEWSNNTP_ERROR_STREAM;
1283
1284 r = parse_response(f, response);
1285 switch (r) {
1286 case 480:
1287 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
1288
1289 case 381:
1290 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
1291
1292 case 200:
1293 return NEWSNNTP_NO_ERROR;
1294
1295 default:
1296 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
1297 }
1298}
1299
1300/* ********************** DATE ***************************** */
1301
1302#define strfcpy(a,b,c) {if (c) {strncpy(a,b,c);a[c-1]=0;}}
1303
1304int newsnntp_date(newsnntp * f, struct tm * tm)
1305{
1306 char command[NNTP_STRING_SIZE];
1307 int r;
1308 char * response;
1309 char year[5];
1310 char month[3];
1311 char day[3];
1312 char hour[3];
1313 char minute[3];
1314 char second[3];
1315
1316 snprintf(command, NNTP_STRING_SIZE, "DATE\r\n");
1317 r = send_command(f, command);
1318 if (r == -1)
1319 return NEWSNNTP_ERROR_STREAM;
1320
1321 response = read_line(f);
1322 if (response == NULL)
1323 return NEWSNNTP_ERROR_STREAM;
1324
1325 r = parse_response(f, response);
1326
1327 switch (r) {
1328 case 111:
1329 strfcpy(year, f->nntp_response, 4);
1330 strfcpy(month, f->nntp_response + 4, 2);
1331 strfcpy(day, f->nntp_response + 6, 2);
1332 strfcpy(hour, f->nntp_response + 8, 2);
1333 strfcpy(minute, f->nntp_response + 10, 2);
1334 strfcpy(second, f->nntp_response + 12, 2);
1335
1336 tm->tm_year = atoi(year);
1337 tm->tm_mon = atoi(month);
1338 tm->tm_mday = atoi(day);
1339 tm->tm_hour = atoi(hour);
1340 tm->tm_min = atoi(minute);
1341 tm->tm_sec = atoi(second);
1342
1343 return NEWSNNTP_NO_ERROR;
1344
1345 default:
1346 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
1347 }
1348}
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358/* ********************** XHDR ***************************** */
1359
1360static struct newsnntp_xhdr_resp_item * xhdr_resp_item_new(uint32_t article,
1361 char * value)
1362{
1363 struct newsnntp_xhdr_resp_item * n;
1364
1365 n = malloc(sizeof(* n));
1366 if (n == NULL)
1367 return NULL;
1368
1369 n->hdr_value = strdup(value);
1370 if (n->hdr_value == NULL) {
1371 free(n);
1372 return NULL;
1373 }
1374
1375 n->hdr_article = article;
1376
1377 return n;
1378}
1379
1380static void xhdr_resp_item_free(struct newsnntp_xhdr_resp_item * n)
1381{
1382 if (n->hdr_value)
1383 free(n->hdr_value);
1384 free(n);
1385}
1386
1387static void xhdr_resp_list_free(clist * l)
1388{
1389 clist_foreach(l, (clist_func) xhdr_resp_item_free, NULL);
1390 clist_free(l);
1391}
1392
1393static clist * read_xhdr_resp_list(newsnntp * f);
1394
1395static int newsnntp_xhdr_resp(newsnntp * f, clist ** result);
1396
1397int newsnntp_xhdr_single(newsnntp * f, const char * header, uint32_t article,
1398 clist ** result)
1399{
1400 char command[NNTP_STRING_SIZE];
1401 int r;
1402
1403 snprintf(command, NNTP_STRING_SIZE, "XHDR %s %i\r\n", header, article);
1404 r = send_command(f, command);
1405 if (r == -1)
1406 return NEWSNNTP_ERROR_STREAM;
1407
1408 return newsnntp_xhdr_resp(f, result);
1409}
1410
1411int newsnntp_xhdr_range(newsnntp * f, const char * header,
1412 uint32_t rangeinf, uint32_t rangesup,
1413 clist ** result)
1414{
1415 char command[NNTP_STRING_SIZE];
1416 int r;
1417
1418 snprintf(command, NNTP_STRING_SIZE, "XHDR %s %i-%i\r\n", header,
1419 rangeinf, rangesup);
1420 r = send_command(f, command);
1421 if (r == -1)
1422 return NEWSNNTP_ERROR_STREAM;
1423
1424 return newsnntp_xhdr_resp(f, result);
1425}
1426
1427void newsnntp_xhdr_free(clist * l)
1428{
1429 xhdr_resp_list_free(l);
1430}
1431
1432static int newsnntp_xhdr_resp(newsnntp * f, clist ** result)
1433{
1434 int r;
1435 char * response;
1436
1437 response = read_line(f);
1438 if (response == NULL)
1439 return NEWSNNTP_ERROR_STREAM;
1440
1441 r = parse_response(f, response);
1442
1443 switch (r) {
1444 case 480:
1445 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
1446
1447 case 381:
1448 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
1449
1450 case 221:
1451 * result = read_xhdr_resp_list(f);
1452 return NEWSNNTP_NO_ERROR;
1453
1454 case 412:
1455 return NEWSNNTP_ERROR_NO_NEWSGROUP_SELECTED;
1456
1457 case 420:
1458 return NEWSNNTP_ERROR_NO_ARTICLE_SELECTED;
1459
1460 case 430:
1461 return NEWSNNTP_ERROR_ARTICLE_NOT_FOUND;
1462
1463 case 502:
1464 return NEWSNNTP_ERROR_NO_PERMISSION;
1465
1466 default:
1467 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
1468 }
1469}
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484/* ********************** XOVER ***************************** */
1485
1486static struct newsnntp_xover_resp_item *
1487xover_resp_item_new(uint32_t article,
1488 char * subject,
1489 char * author,
1490 char * date,
1491 char * message_id,
1492 char * references,
1493 size_t size,
1494 uint32_t line_count,
1495 clist * others)
1496{
1497 struct newsnntp_xover_resp_item * n;
1498
1499 n = malloc(sizeof(* n));
1500 if (n == NULL)
1501 return NULL;
1502
1503 n->ovr_subject = strdup(subject);
1504 if (n->ovr_subject == NULL) {
1505 free(n);
1506 return NULL;
1507 }
1508
1509 n->ovr_author = strdup(author);
1510 if (n->ovr_author == NULL) {
1511 free(n->ovr_subject);
1512 free(n);
1513 return NULL;
1514 }
1515
1516 n->ovr_date = strdup(date);
1517 if (n->ovr_date == NULL) {
1518 free(n->ovr_subject);
1519 free(n->ovr_author);
1520 free(n);
1521 return NULL;
1522 }
1523
1524 n->ovr_message_id = strdup(message_id);
1525 if (n->ovr_message_id == NULL) {
1526 free(n->ovr_subject);
1527 free(n->ovr_author);
1528 free(n->ovr_date);
1529 free(n);
1530 return NULL;
1531 }
1532
1533 n->ovr_references = strdup(references);
1534 if (n->ovr_references == NULL) {
1535 free(n->ovr_subject);
1536 free(n->ovr_author);
1537 free(n->ovr_date);
1538 free(n->ovr_message_id);
1539 free(n);
1540 return NULL;
1541 }
1542
1543 n->ovr_article = article;
1544 n->ovr_size = size;
1545 n->ovr_line_count = line_count;
1546 n->ovr_others = others;
1547
1548 return n;
1549}
1550
1551void xover_resp_item_free(struct newsnntp_xover_resp_item * n)
1552{
1553 if (n->ovr_subject)
1554 free(n->ovr_subject);
1555 if (n->ovr_author)
1556 free(n->ovr_author);
1557 if (n->ovr_date)
1558 free(n->ovr_date);
1559 if (n->ovr_message_id)
1560 free(n->ovr_message_id);
1561 if (n->ovr_references)
1562 free(n->ovr_references);
1563 clist_foreach(n->ovr_others, (clist_func) free, NULL);
1564 clist_free(n->ovr_others);
1565
1566 free(n);
1567}
1568
1569void newsnntp_xover_resp_list_free(clist * l)
1570{
1571 clist_foreach(l, (clist_func) xover_resp_item_free, NULL);
1572 clist_free(l);
1573}
1574
1575static clist * read_xover_resp_list(newsnntp * f);
1576
1577
1578static int newsnntp_xover_resp(newsnntp * f, clist ** result);
1579
1580int newsnntp_xover_single(newsnntp * f, uint32_t article,
1581 struct newsnntp_xover_resp_item ** result)
1582{
1583 char command[NNTP_STRING_SIZE];
1584 int r;
1585 clist * list;
1586 clistiter * cur;
1587 struct newsnntp_xover_resp_item * item;
1588
1589 snprintf(command, NNTP_STRING_SIZE, "XOVER %i\r\n", article);
1590 r = send_command(f, command);
1591 if (r == -1)
1592 return NEWSNNTP_ERROR_STREAM;
1593
1594 r = newsnntp_xover_resp(f, &list);
1595 if (r != NEWSNNTP_NO_ERROR)
1596 return r;
1597
1598 cur = clist_begin(list);
1599 item = clist_content(cur);
1600 clist_free(list);
1601
1602 * result = item;
1603
1604 return r;
1605}
1606
1607int newsnntp_xover_range(newsnntp * f, uint32_t rangeinf, uint32_t rangesup,
1608 clist ** result)
1609{
1610 int r;
1611 char command[NNTP_STRING_SIZE];
1612
1613 snprintf(command, NNTP_STRING_SIZE, "XOVER %i-%i\r\n", rangeinf, rangesup);
1614 r = send_command(f, command);
1615 if (r == -1)
1616 return NEWSNNTP_ERROR_STREAM;
1617
1618 return newsnntp_xover_resp(f, result);
1619}
1620
1621static int newsnntp_xover_resp(newsnntp * f, clist ** result)
1622{
1623 int r;
1624 char * response;
1625
1626 response = read_line(f);
1627 if (response == NULL)
1628 return NEWSNNTP_ERROR_STREAM;
1629
1630 r = parse_response(f, response);
1631
1632 switch (r) {
1633 case 480:
1634 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
1635
1636 case 381:
1637 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
1638
1639 case 224:
1640 * result = read_xover_resp_list(f);
1641 return NEWSNNTP_NO_ERROR;
1642
1643 case 412:
1644 return NEWSNNTP_ERROR_NO_NEWSGROUP_SELECTED;
1645
1646 case 420:
1647 return NEWSNNTP_ERROR_NO_ARTICLE_SELECTED;
1648
1649 case 502:
1650 return NEWSNNTP_ERROR_NO_PERMISSION;
1651
1652 default:
1653 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
1654 }
1655}
1656
1657
1658
1659
1660
1661
1662
1663/* ********************** AUTHINFO GENERIC ***************************** */
1664
1665int newsnntp_authinfo_generic(newsnntp * f, const char * authentificator,
1666 const char * arguments)
1667{
1668 char command[NNTP_STRING_SIZE];
1669 int r;
1670 char * response;
1671
1672 snprintf(command, NNTP_STRING_SIZE, "AUTHINFO GENERIC %s %s\r\n",
1673 authentificator, arguments);
1674 r = send_command(f, command);
1675 if (r == -1)
1676 return NEWSNNTP_ERROR_STREAM;
1677
1678 response = read_line(f);
1679 if (response == NULL)
1680 return NEWSNNTP_ERROR_STREAM;
1681
1682 r = parse_response(f, response);
1683
1684 switch (r) {
1685 case 480:
1686 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
1687
1688 case 381:
1689 return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
1690
1691 case 281:
1692 return NEWSNNTP_NO_ERROR;
1693
1694 case 500:
1695 return NEWSNNTP_ERROR_COMMAND_NOT_UNDERSTOOD;
1696
1697 case 501:
1698 return NEWSNNTP_ERROR_COMMAND_NOT_SUPPORTED;
1699
1700 case 502:
1701 return NEWSNNTP_ERROR_NO_PERMISSION;
1702
1703 case 503:
1704 return NEWSNNTP_ERROR_PROGRAM_ERROR;
1705
1706 default:
1707 return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
1708 }
1709}
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729static int parse_space(char ** line)
1730{
1731 char * p;
1732
1733 p = * line;
1734
1735 while ((* p == ' ') || (* p == '\t'))
1736 p ++;
1737
1738 if (p != * line) {
1739 * line = p;
1740 return TRUE;
1741 }
1742 else
1743 return FALSE;
1744}
1745
1746static char * cut_token(char * line)
1747{
1748 char * p;
1749 char * p_tab;
1750 char * p_space;
1751
1752 p = line;
1753
1754 p_space = strchr(line, ' ');
1755 p_tab = strchr(line, '\t');
1756 if (p_tab == NULL)
1757 p = p_space;
1758 else if (p_space == NULL)
1759 p = p_tab;
1760 else {
1761 if (p_tab < p_space)
1762 p = p_tab;
1763 else
1764 p = p_space;
1765 }
1766 if (p == NULL)
1767 return NULL;
1768 * p = 0;
1769 p ++;
1770
1771 return p;
1772}
1773
1774static int parse_response(newsnntp * f, char * response)
1775{
1776 int code;
1777
1778 code = strtol(response, &response, 10);
1779
1780 if (response == NULL) {
1781 f->nntp_response = NULL;
1782 return code;
1783 }
1784
1785 parse_space(&response);
1786
1787 if (mmap_string_assign(f->nntp_response_buffer, response) != NULL)
1788 f->nntp_response = f->nntp_response_buffer->str;
1789 else
1790 f->nntp_response = NULL;
1791
1792 return code;
1793}
1794
1795
1796static char * read_line(newsnntp * f)
1797{
1798 return mailstream_read_line_remove_eol(f->nntp_stream, f->nntp_stream_buffer);
1799}
1800
1801static char * read_multiline(newsnntp * f, size_t size,
1802 MMAPString * multiline_buffer)
1803{
1804 return mailstream_read_multiline(f->nntp_stream, size,
1805 f->nntp_stream_buffer, multiline_buffer,
1806 f->nntp_progr_rate, f->nntp_progr_fun);
1807}
1808
1809
1810
1811
1812
1813
1814
1815static int parse_group_info(char * response,
1816 struct newsnntp_group_info ** result)
1817{
1818 char * line;
1819 uint32_t first;
1820 uint32_t last;
1821 uint32_t count;
1822 char * name;
1823 struct newsnntp_group_info * info;
1824
1825 line = response;
1826
1827 count = strtoul(line, &line, 10);
1828 if (!parse_space(&line))
1829 return FALSE;
1830
1831 first = strtoul(line, &line, 10);
1832 if (!parse_space(&line))
1833 return FALSE;
1834
1835 last = strtoul(line, &line, 10);
1836 if (!parse_space(&line))
1837 return FALSE;
1838
1839 name = line;
1840
1841 info = group_info_init(name, first, last, count, FALSE);
1842 if (info == NULL)
1843 return FALSE;
1844
1845 * result = info;
1846
1847 return TRUE;
1848}
1849
1850
1851static clist * read_groups_list(newsnntp * f)
1852{
1853 char * line;
1854 char * group_name;
1855 uint32_t first;
1856 uint32_t last;
1857 uint32_t count;
1858 int type;
1859 clist * groups_list;
1860 struct newsnntp_group_info * n;
1861 int r;
1862
1863 groups_list = clist_new();
1864 if (groups_list == NULL)
1865 goto err;
1866
1867 while (1) {
1868 char * p;
1869
1870 line = read_line(f);
1871 if (line == NULL)
1872 goto free_list;
1873
1874 if (mailstream_is_end_multiline(line))
1875 break;
1876
1877 p = cut_token(line);
1878 if (p == NULL)
1879 continue;
1880
1881 group_name = line;
1882 line = p;
1883
1884 last = strtol(line, &line, 10);
1885 if (!parse_space(&line))
1886 continue;
1887
1888 first = strtol(line, &line, 10);
1889 if (!parse_space(&line))
1890 continue;
1891
1892 count = last - first + 1;
1893
1894 type = * line;
1895
1896 n = group_info_init(group_name, first, last, count, type);
1897 if (n == NULL)
1898 goto free_list;
1899
1900 r = clist_append(groups_list, n);
1901 if (r < 0) {
1902 group_info_free(n);
1903 goto free_list;
1904 }
1905 }
1906
1907 return groups_list;
1908
1909 free_list:
1910 group_info_list_free(groups_list);
1911 err:
1912 return NULL;
1913}
1914
1915
1916static clist * read_headers_list(newsnntp * f)
1917{
1918 char * line;
1919 clist * headers_list;
1920 char * header;
1921 int r;
1922
1923 headers_list = clist_new();
1924 if (headers_list == NULL)
1925 goto err;
1926
1927 while (1) {
1928 line = read_line(f);
1929
1930 if (line == NULL)
1931 goto free_list;
1932
1933 if (mailstream_is_end_multiline(line))
1934 break;
1935
1936 header = strdup(line);
1937 if (header == NULL)
1938 goto free_list;
1939
1940 r = clist_append(headers_list, header);
1941 if (r < 0) {
1942 free(header);
1943 goto free_list;
1944 }
1945 }
1946
1947 return headers_list;
1948
1949 free_list:
1950 headers_list_free(headers_list);
1951 err:
1952 return NULL;
1953}
1954
1955
1956
1957
1958static clist * read_group_time_list(newsnntp * f)
1959{
1960 char * line;
1961 char * group_name;
1962 time_t date;
1963 char * email;
1964 clist * group_time_list;
1965 struct newsnntp_group_time * n;
1966 int r;
1967
1968 group_time_list = clist_new();
1969 if (group_time_list == NULL)
1970 goto err;
1971
1972 while (1) {
1973 char * p;
1974 char * remaining;
1975
1976 line = read_line(f);
1977
1978 if (line == NULL)
1979 goto free_list;
1980
1981 if (mailstream_is_end_multiline(line))
1982 break;
1983
1984 p = cut_token(line);
1985 if (p == NULL)
1986 continue;
1987
1988 date = strtoul(p, &remaining, 10);
1989
1990 p = remaining;
1991 parse_space(&p);
1992
1993 email = p;
1994
1995 group_name = line;
1996
1997 n = group_time_new(group_name, date, email);
1998 if (n == NULL)
1999 goto free_list;
2000
2001 r = clist_append(group_time_list, n);
2002 if (r < 0) {
2003 group_time_free(n);
2004 goto free_list;
2005 }
2006 }
2007
2008 return group_time_list;
2009
2010 free_list:
2011 group_time_list_free(group_time_list);
2012 err:
2013 return NULL;
2014}
2015
2016
2017
2018
2019static clist * read_distrib_value_meaning_list(newsnntp * f)
2020{
2021 char * line;
2022 char * value;
2023 char * meaning;
2024 clist * distrib_value_meaning_list;
2025 struct newsnntp_distrib_value_meaning * n;
2026 int r;
2027
2028 distrib_value_meaning_list = clist_new();
2029 if (distrib_value_meaning_list == NULL)
2030 goto err;
2031
2032 while (1) {
2033 char * p;
2034
2035 line = read_line(f);
2036 if (line == NULL)
2037 goto free_list;
2038
2039 if (mailstream_is_end_multiline(line))
2040 break;
2041
2042 p = cut_token(line);
2043 if (p == NULL)
2044 continue;
2045
2046 meaning = p;
2047
2048 value = line;
2049
2050 n = distrib_value_meaning_new(value, meaning);
2051 if (n == NULL)
2052 goto free_list;
2053
2054 r = clist_append(distrib_value_meaning_list, n);
2055 if (r < 0) {
2056 distrib_value_meaning_free(n);
2057 goto free_list;
2058 }
2059 }
2060
2061 return distrib_value_meaning_list;
2062
2063 free_list:
2064 distrib_value_meaning_list_free(distrib_value_meaning_list);
2065 err:
2066 return NULL;
2067}
2068
2069
2070
2071
2072static clist * read_distrib_default_value_list(newsnntp * f)
2073{
2074 char * line;
2075 uint32_t weight;
2076 char * group_pattern;
2077 char * meaning;
2078 clist * distrib_default_value_list;
2079 struct newsnntp_distrib_default_value * n;
2080 int r;
2081
2082 distrib_default_value_list = clist_new();
2083 if (distrib_default_value_list == NULL)
2084 goto err;
2085
2086 while (1) {
2087 char * p;
2088 char * remaining;
2089
2090 line = read_line(f);
2091 if (line == NULL)
2092 goto free_list;
2093
2094 if (mailstream_is_end_multiline(line))
2095 break;
2096
2097 p = line;
2098
2099 weight = strtoul(p, &remaining, 10);
2100 p = remaining;
2101 parse_space(&p);
2102
2103 p = cut_token(line);
2104 if (p == NULL)
2105 continue;
2106
2107 meaning = p;
2108 group_pattern = line;
2109
2110 n = distrib_default_value_new(weight, group_pattern, meaning);
2111 if (n == NULL)
2112 goto free_list;
2113
2114 r = clist_append(distrib_default_value_list, n);
2115 if (r < 0) {
2116 distrib_default_value_free(n);
2117 goto free_list;
2118 }
2119 }
2120
2121 return distrib_default_value_list;
2122
2123 free_list:
2124 distrib_default_value_list_free(distrib_default_value_list);
2125 err:
2126 return NULL;
2127}
2128
2129
2130
2131static clist * read_group_description_list(newsnntp * f)
2132{
2133 char * line;
2134 char * group_name;
2135 char * description;
2136 clist * group_description_list;
2137 struct newsnntp_group_description * n;
2138 int r;
2139
2140 group_description_list = clist_new();
2141 if (group_description_list == NULL)
2142 goto err;
2143
2144 while (1) {
2145 char * p;
2146
2147 line = read_line(f);
2148 if (line == NULL)
2149 goto free_list;
2150
2151 if (mailstream_is_end_multiline(line))
2152 break;
2153
2154 p = cut_token(line);
2155 if (p == NULL)
2156 continue;
2157
2158 description = p;
2159
2160 group_name = line;
2161
2162 n = group_description_new(group_name, description);
2163 if (n == NULL)
2164 goto free_list;
2165
2166 r = clist_append(group_description_list, n);
2167 if (r < 0) {
2168 group_description_free(n);
2169 goto free_list;
2170 }
2171 }
2172
2173 return group_description_list;
2174
2175 free_list:
2176 group_description_list_free(group_description_list);
2177 err:
2178 return NULL;
2179}
2180
2181
2182
2183static clist * read_subscriptions_list(newsnntp * f)
2184{
2185 char * line;
2186 clist * subscriptions_list;
2187 char * group_name;
2188 int r;
2189
2190 subscriptions_list = clist_new();
2191 if (subscriptions_list == NULL)
2192 goto err;
2193
2194 while (1) {
2195 line = read_line(f);
2196
2197 if (line == NULL)
2198 goto free_list;
2199
2200 if (mailstream_is_end_multiline(line))
2201 break;
2202
2203 group_name = strdup(line);
2204 if (group_name == NULL)
2205 goto free_list;
2206
2207 r = clist_append(subscriptions_list, group_name);
2208 if (r < 0) {
2209 free(group_name);
2210 goto free_list;
2211 }
2212 }
2213
2214 return subscriptions_list;
2215
2216 free_list:
2217 subscriptions_list_free(subscriptions_list);
2218 err:
2219 return NULL;
2220}
2221
2222
2223
2224static clist * read_articles_list(newsnntp * f)
2225{
2226 char * line;
2227 clist * articles_list;
2228 uint32_t * article_num;
2229 int r;
2230
2231 articles_list = clist_new();
2232 if (articles_list == NULL)
2233 goto err;
2234
2235 while (1) {
2236 line = read_line(f);
2237 if (line == NULL)
2238 goto free_list;
2239
2240 if (mailstream_is_end_multiline(line))
2241 break;
2242
2243 article_num = malloc(sizeof(* article_num));
2244 if (article_num == NULL)
2245 goto free_list;
2246 * article_num = atoi(line);
2247
2248 r = clist_append(articles_list, article_num);
2249 if (r < 0) {
2250 free(article_num);
2251 goto free_list;
2252 }
2253 }
2254
2255 return articles_list;
2256
2257 free_list:
2258 articles_list_free(articles_list);
2259 err:
2260 return NULL;
2261}
2262
2263static clist * read_xhdr_resp_list(newsnntp * f)
2264{
2265 char * line;
2266 uint32_t article;
2267 char * value;
2268 clist * xhdr_resp_list;
2269 struct newsnntp_xhdr_resp_item * n;
2270 int r;
2271
2272 xhdr_resp_list = clist_new();
2273 if (xhdr_resp_list == NULL)
2274 goto err;
2275
2276 while (1) {
2277 line = read_line(f);
2278
2279 if (line == NULL)
2280 goto free_list;
2281
2282 if (mailstream_is_end_multiline(line))
2283 break;
2284
2285 article = strtoul(line, &line, 10);
2286 if (!parse_space(&line))
2287 continue;
2288
2289 value = line;
2290
2291 n = xhdr_resp_item_new(article, value);
2292 if (n == NULL)
2293 goto free_list;
2294
2295 r = clist_append(xhdr_resp_list, n);
2296 if (r < 0) {
2297 xhdr_resp_item_free(n);
2298 goto free_list;
2299 }
2300 }
2301
2302 return xhdr_resp_list;
2303
2304 free_list:
2305 xhdr_resp_list_free(xhdr_resp_list);
2306 err:
2307 return NULL;
2308}
2309
2310
2311static clist * read_xover_resp_list(newsnntp * f)
2312{
2313 char * line;
2314 clist * xover_resp_list;
2315 struct newsnntp_xover_resp_item * n;
2316 clist * values_list;
2317 clistiter * current;
2318 uint32_t article;
2319 char * subject;
2320 char * author;
2321 char * date;
2322 char * message_id;
2323 char * references;
2324 size_t size;
2325 uint32_t line_count;
2326 clist * others;
2327 int r;
2328
2329 xover_resp_list = clist_new();
2330 if (xover_resp_list == NULL)
2331 goto err;
2332
2333 while (1) {
2334 char * p;
2335
2336 line = read_line(f);
2337
2338 if (line == NULL)
2339 goto free_list;
2340
2341 if (mailstream_is_end_multiline(line))
2342 break;
2343
2344 /* parse the data separated with \t */
2345
2346 values_list = clist_new();
2347 if (values_list == NULL)
2348 goto free_list;
2349
2350 while ((p = strchr(line, '\t')) != NULL) {
2351 * p = 0;
2352 p ++;
2353
2354 r = clist_append(values_list, line);
2355 if (r < 0)
2356 goto free_values_list;
2357 line = p;
2358 }
2359
2360 r = clist_append(values_list, line);
2361 if (r < 0)
2362 goto free_values_list;
2363
2364 /* set the known data */
2365 current = clist_begin(values_list);
2366 article = atoi((char *) clist_content(current));
2367
2368 current = clist_next(current);
2369 if (current == NULL) {
2370 clist_free(values_list);
2371 continue;
2372 }
2373 subject = clist_content(current);
2374
2375 current = clist_next(current);
2376 if (current == NULL) {
2377 clist_free(values_list);
2378 continue;
2379 }
2380 author = clist_content(current);
2381
2382 current = clist_next(current);
2383 if (current == NULL) {
2384 clist_free(values_list);
2385 continue;
2386 }
2387 date = clist_content(current);
2388
2389 current = clist_next(current);
2390 if (current == NULL) {
2391 clist_free(values_list);
2392 continue;
2393 }
2394 message_id = clist_content(current);
2395
2396 current = clist_next(current);
2397 if (current == NULL) {
2398 clist_free(values_list);
2399 continue;
2400 }
2401 references = clist_content(current);
2402
2403 current = clist_next(current);
2404 if (current == NULL) {
2405 clist_free(values_list);
2406 continue;
2407 }
2408 size = atoi((char *) clist_content(current));
2409
2410 current = clist_next(current);
2411 if (current == NULL) {
2412 clist_free(values_list);
2413 continue;
2414 }
2415 line_count = atoi((char *) clist_content(current));
2416
2417 current = clist_next(current);
2418
2419 /* make a copy of the other data */
2420 others = clist_new();
2421 if (others == NULL) {
2422 goto free_values_list;
2423 }
2424
2425 while (current) {
2426 char * val;
2427
2428 val = strdup(clist_content(current));
2429 if (val == NULL) {
2430 clist_foreach(others, (clist_func) free, NULL);
2431 clist_free(others);
2432 goto free_list;
2433 }
2434
2435 r = clist_append(others, val);
2436 if (r < 0) {
2437 goto free_list;
2438 }
2439
2440 current = clist_next(current);
2441 }
2442
2443 clist_free(values_list);
2444
2445 n = xover_resp_item_new(article, subject, author, date, message_id,
2446 references, size, line_count, others);
2447 if (n == NULL) {
2448 clist_foreach(others, (clist_func) free, NULL);
2449 clist_free(others);
2450 goto free_list;
2451 }
2452
2453 r = clist_append(xover_resp_list, n);
2454 if (r < 0) {
2455 xover_resp_item_free(n);
2456 goto free_list;
2457 }
2458 }
2459
2460 return xover_resp_list;
2461
2462 free_list:
2463 newsnntp_xover_resp_list_free(xover_resp_list);
2464 err:
2465 return NULL;
2466
2467 free_values_list:
2468 clist_foreach(values_list, (clist_func) free, NULL);
2469 clist_free(values_list);
2470 return NULL;
2471}
2472
2473static int send_command(newsnntp * f, char * command)
2474{
2475 ssize_t r;
2476
2477 r = mailstream_write(f->nntp_stream, command, strlen(command));
2478 if (r == -1)
2479 return -1;
2480
2481 r = mailstream_flush(f->nntp_stream);
2482 if (r == -1)
2483 return -1;
2484
2485 return 0;
2486}
diff --git a/kmicromail/libetpan/nntp/newsnntp.h b/kmicromail/libetpan/nntp/newsnntp.h
new file mode 100644
index 0000000..13360d0
--- a/dev/null
+++ b/kmicromail/libetpan/nntp/newsnntp.h
@@ -0,0 +1,188 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NEWSNNTP_H
37
38#define NEWSNNTP_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45#include <sys/types.h>
46#include <time.h>
47
48#include <libetpan/clist.h>
49#include <libetpan/mailstream.h>
50#include <libetpan/newsnntp_socket.h>
51#include <libetpan/newsnntp_ssl.h>
52#include <libetpan/newsnntp_types.h>
53
54
55newsnntp * newsnntp_new(size_t nntp_progr_rate,
56 progress_function * nntp_progr_fun);
57void newsnntp_free(newsnntp * f);
58
59int newsnntp_quit(newsnntp * f);
60int newsnntp_connect(newsnntp * f, mailstream * s);
61
62int newsnntp_head(newsnntp * f, uint32_t index, char ** result,
63 size_t * result_len);
64int newsnntp_article(newsnntp * f, uint32_t index, char ** result,
65 size_t * result_len);
66int newsnntp_body(newsnntp * f, uint32_t index, char ** result,
67 size_t * result_len);
68
69void newsnntp_head_free(char * str);
70void newsnntp_article_free(char * str);
71void newsnntp_body_free(char * str);
72
73int newsnntp_mode_reader(newsnntp * f);
74
75int newsnntp_date(newsnntp * f, struct tm * tm);
76
77int newsnntp_authinfo_generic(newsnntp * f, const char * authentificator,
78 const char * arguments);
79
80int newsnntp_authinfo_username(newsnntp * f, const char * username);
81int newsnntp_authinfo_password(newsnntp * f, const char * password);
82
83int newsnntp_post(newsnntp * f, const char * message, size_t size);
84
85
86
87
88
89
90/******************* requests ******************************/
91
92int newsnntp_group(newsnntp * f, const char * groupname,
93 struct newsnntp_group_info ** info);
94void newsnntp_group_free(struct newsnntp_group_info * info);
95
96/*
97 elements are struct newsnntp_group_info *
98 */
99
100int newsnntp_list(newsnntp * f, clist ** result);
101void newsnntp_list_free(clist * l);
102
103/*
104 elements are char *
105*/
106
107int newsnntp_list_overview_fmt(newsnntp * f, clist ** result);
108void newsnntp_list_overview_fmt_free(clist * l);
109
110/*
111 elements are struct newsnntp_group_info *
112*/
113
114int newsnntp_list_active(newsnntp * f, const char * wildcard, clist ** result);
115void newsnntp_list_active_free(clist * l);
116
117/*
118 elements are struct newsnntp_group_time *
119*/
120
121int newsnntp_list_active_times(newsnntp * f, clist ** result);
122void newsnntp_list_active_times_free(clist * l);
123
124/*
125 elements are struct newsnntp_distrib_value_meaning *
126*/
127
128int newsnntp_list_distribution(newsnntp * f, clist ** result);
129void newsnntp_list_distribution_free(clist * l);
130
131/*
132 elements are struct newsnntp_distrib_default_value *
133*/
134
135int newsnntp_list_distrib_pats(newsnntp * f, clist ** result);
136void newsnntp_list_distrib_pats_free(clist * l);
137
138/*
139 elements are struct newsnntp_group_description *
140*/
141
142int newsnntp_list_newsgroups(newsnntp * f, const char * pattern,
143 clist ** result);
144void newsnntp_list_newsgroups_free(clist * l);
145
146/*
147 elements are char *
148*/
149
150int newsnntp_list_subscriptions(newsnntp * f, clist ** result);
151void newsnntp_list_subscriptions_free(clist * l);
152
153/*
154 elements are uint32_t *
155*/
156
157int newsnntp_listgroup(newsnntp * f, const char * group_name,
158 clist ** result);
159void newsnntp_listgroup_free(clist * l);
160
161/*
162 elements are struct newsnntp_xhdr_resp_item *
163*/
164
165int newsnntp_xhdr_single(newsnntp * f, const char * header, uint32_t article,
166 clist ** result);
167int newsnntp_xhdr_range(newsnntp * f, const char * header,
168 uint32_t rangeinf, uint32_t rangesup,
169 clist ** result);
170void newsnntp_xhdr_free(clist * l);
171
172/*
173 elements are struct newsnntp_xover_resp_item *
174*/
175
176int newsnntp_xover_single(newsnntp * f, uint32_t article,
177 struct newsnntp_xover_resp_item ** result);
178int newsnntp_xover_range(newsnntp * f, uint32_t rangeinf, uint32_t rangesup,
179 clist ** result);
180void newsnntp_xover_free(clist * l);
181void xover_resp_item_free(struct newsnntp_xover_resp_item * n);
182void newsnntp_xover_resp_list_free(clist * l);
183
184#ifdef __cplusplus
185}
186#endif
187
188#endif
diff --git a/kmicromail/libetpan/nntp/newsnntp_socket.c b/kmicromail/libetpan/nntp/newsnntp_socket.c
new file mode 100644
index 0000000..245839f
--- a/dev/null
+++ b/kmicromail/libetpan/nntp/newsnntp_socket.c
@@ -0,0 +1,74 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "newsnntp_socket.h"
37
38#include "newsnntp.h"
39
40#include "connect.h"
41
42#include <netinet/in.h>
43#include <unistd.h>
44
45#define DEFAULT_NNTP_PORT 119
46#define SERVICE_NAME_NNTP "nntp"
47#define SERVICE_TYPE_TCP "tcp"
48
49int newsnntp_socket_connect(newsnntp * f, const char * server, uint16_t port)
50{
51 int s;
52 mailstream * stream;
53
54 if (port == 0) {
55 port = mail_get_service_port(SERVICE_NAME_NNTP, SERVICE_TYPE_TCP);
56 if (port == 0)
57 port = DEFAULT_NNTP_PORT;
58 port = ntohs(port);
59 }
60
61 /* Connection */
62
63 s = mail_tcp_connect(server, port);
64 if (s == -1)
65 return NEWSNNTP_ERROR_CONNECTION_REFUSED;
66
67 stream = mailstream_socket_open(s);
68 if (stream == NULL) {
69 close(s);
70 return NEWSNNTP_ERROR_MEMORY;
71 }
72
73 return newsnntp_connect(f, stream);
74}
diff --git a/kmicromail/libetpan/nntp/newsnntp_socket.h b/kmicromail/libetpan/nntp/newsnntp_socket.h
new file mode 100644
index 0000000..fd44b44
--- a/dev/null
+++ b/kmicromail/libetpan/nntp/newsnntp_socket.h
@@ -0,0 +1,55 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NEWSNNTP_SOCKET_H
37
38#define NEWSNNTP_SOCKET_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <sys/types.h>
45#include <inttypes.h>
46
47#include <libetpan/newsnntp_types.h>
48
49int newsnntp_socket_connect(newsnntp * f, const char * server, uint16_t port);
50
51#ifdef __cplusplus
52}
53#endif
54
55#endif
diff --git a/kmicromail/libetpan/nntp/newsnntp_ssl.c b/kmicromail/libetpan/nntp/newsnntp_ssl.c
new file mode 100644
index 0000000..84816bd
--- a/dev/null
+++ b/kmicromail/libetpan/nntp/newsnntp_ssl.c
@@ -0,0 +1,73 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "newsnntp_ssl.h"
37
38#include "newsnntp.h"
39
40#include "connect.h"
41#include <netinet/in.h>
42#include <unistd.h>
43
44#define DEFAULT_NNTPS_PORT 563
45#define SERVICE_NAME_NNTPS "nntps"
46#define SERVICE_TYPE_TCP "tcp"
47
48int newsnntp_ssl_connect(newsnntp * f, const char * server, uint16_t port)
49{
50 int s;
51 mailstream * stream;
52
53 if (port == 0) {
54 port = mail_get_service_port(SERVICE_NAME_NNTPS, SERVICE_TYPE_TCP);
55 if (port == 0)
56 port = DEFAULT_NNTPS_PORT;
57 port = ntohs(port);
58 }
59
60 /* Connection */
61
62 s = mail_tcp_connect(server, port);
63 if (s == -1)
64 return NEWSNNTP_ERROR_CONNECTION_REFUSED;
65
66 stream = mailstream_ssl_open(s);
67 if (stream == NULL) {
68 close(s);
69 return NEWSNNTP_ERROR_CONNECTION_REFUSED;
70 }
71
72 return newsnntp_connect(f, stream);
73}
diff --git a/kmicromail/libetpan/nntp/newsnntp_ssl.h b/kmicromail/libetpan/nntp/newsnntp_ssl.h
new file mode 100644
index 0000000..59eace5
--- a/dev/null
+++ b/kmicromail/libetpan/nntp/newsnntp_ssl.h
@@ -0,0 +1,55 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NEWSNNTP_SSL_H
37
38#define NEWSNNTP_SSL_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <sys/types.h>
45#include <inttypes.h>
46
47#include <libetpan/newsnntp_types.h>
48
49int newsnntp_ssl_connect(newsnntp * f, const char * server, uint16_t port);
50
51#ifdef __cplusplus
52}
53#endif
54
55#endif
diff --git a/kmicromail/libetpan/nntp/newsnntp_types.h b/kmicromail/libetpan/nntp/newsnntp_types.h
new file mode 100644
index 0000000..0501088
--- a/dev/null
+++ b/kmicromail/libetpan/nntp/newsnntp_types.h
@@ -0,0 +1,144 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef NEWSNNTP_TYPES_H
37
38#define NEWSNNTP_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45#include <libetpan/clist.h>
46
47#include <libetpan/mailstream.h>
48#include <libetpan/mmapstring.h>
49
50enum {
51 NEWSNNTP_NO_ERROR = 0,
52 NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME,
53 NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD,
54 NEWSNNTP_ERROR_STREAM,
55 NEWSNNTP_ERROR_UNEXPECTED,
56 NEWSNNTP_ERROR_NO_NEWSGROUP_SELECTED,
57 NEWSNNTP_ERROR_NO_ARTICLE_SELECTED,
58 NEWSNNTP_ERROR_INVALID_ARTICLE_NUMBER,
59 NEWSNNTP_ERROR_ARTICLE_NOT_FOUND,
60 NEWSNNTP_ERROR_UNEXPECTED_RESPONSE,
61 NEWSNNTP_ERROR_INVALID_RESPONSE,
62 NEWSNNTP_ERROR_NO_SUCH_NEWS_GROUP,
63 NEWSNNTP_ERROR_POSTING_NOT_ALLOWED,
64 NEWSNNTP_ERROR_POSTING_FAILED,
65 NEWSNNTP_ERROR_PROGRAM_ERROR,
66 NEWSNNTP_ERROR_NO_PERMISSION,
67 NEWSNNTP_ERROR_COMMAND_NOT_UNDERSTOOD,
68 NEWSNNTP_ERROR_COMMAND_NOT_SUPPORTED,
69 NEWSNNTP_ERROR_CONNECTION_REFUSED,
70 NEWSNNTP_ERROR_MEMORY,
71 NEWSNNTP_ERROR_AUTHENTICATION_REJECTED,
72 NEWSNNTP_ERROR_BAD_STATE,
73};
74
75struct newsnntp
76{
77 mailstream * nntp_stream;
78
79 int nntp_readonly;
80
81 uint32_t nntp_progr_rate;
82 progress_function * nntp_progr_fun;
83
84 MMAPString * nntp_stream_buffer;
85 MMAPString * nntp_response_buffer;
86
87 char * nntp_response;
88};
89
90typedef struct newsnntp newsnntp;
91
92struct newsnntp_group_info
93{
94 char * grp_name;
95 uint32_t grp_first;
96 uint32_t grp_last;
97 uint32_t grp_count;
98 char grp_type;
99};
100
101struct newsnntp_group_time {
102 char * grp_name;
103 uint32_t grp_date;
104 char * grp_email;
105};
106
107struct newsnntp_distrib_value_meaning {
108 char * dst_value;
109 char * dst_meaning;
110};
111
112struct newsnntp_distrib_default_value {
113 uint32_t dst_weight;
114 char * dst_group_pattern;
115 char * dst_value;
116};
117
118struct newsnntp_group_description {
119 char * grp_name;
120 char * grp_description;
121};
122
123struct newsnntp_xhdr_resp_item {
124 uint32_t hdr_article;
125 char * hdr_value;
126};
127
128struct newsnntp_xover_resp_item {
129 uint32_t ovr_article;
130 char * ovr_subject;
131 char * ovr_author;
132 char * ovr_date;
133 char * ovr_message_id;
134 char * ovr_references;
135 size_t ovr_size;
136 uint32_t ovr_line_count;
137 clist * ovr_others;
138};
139
140#ifdef __cplusplus
141}
142#endif
143
144#endif
diff --git a/kmicromail/libetpan/pop3/.libs/libmailpop3.a b/kmicromail/libetpan/pop3/.libs/libmailpop3.a
new file mode 100644
index 0000000..55cb819
--- a/dev/null
+++ b/kmicromail/libetpan/pop3/.libs/libmailpop3.a
Binary files differ
diff --git a/kmicromail/libetpan/pop3/mailpop3.c b/kmicromail/libetpan/pop3/mailpop3.c
new file mode 100644
index 0000000..28fafe9
--- a/dev/null
+++ b/kmicromail/libetpan/pop3/mailpop3.c
@@ -0,0 +1,1230 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36/*
37 POP3 Protocol
38
39 RFC 1734
40 RFC 1939
41 RFC 2449
42
43 */
44
45#include "mailpop3.h"
46#include <stdio.h>
47#include <string.h>
48#include "md5.h"
49#include "mail.h"
50#include <stdlib.h>
51
52
53
54
55enum {
56 POP3_STATE_DISCONNECTED,
57 POP3_STATE_AUTHORIZATION,
58 POP3_STATE_TRANSACTION
59};
60
61
62
63/*
64 mailpop3_msg_info structure
65*/
66
67static struct mailpop3_msg_info *
68mailpop3_msg_info_new(unsigned int index, uint32_t size, char * uidl)
69{
70 struct mailpop3_msg_info * msg;
71
72 msg = malloc(sizeof(* msg));
73 if (msg == NULL)
74 return NULL;
75 msg->msg_index = index;
76 msg->msg_size = size;
77 msg->msg_deleted = FALSE;
78 msg->msg_uidl = uidl;
79
80 return msg;
81}
82
83static void mailpop3_msg_info_free(struct mailpop3_msg_info * msg)
84{
85 if (msg->msg_uidl != NULL)
86 free(msg->msg_uidl);
87 free(msg);
88}
89
90static void mailpop3_msg_info_tab_free(carray * msg_tab)
91{
92 unsigned int i;
93
94 for(i = 0 ; i < carray_count(msg_tab) ; i++) {
95 struct mailpop3_msg_info * msg;
96
97 msg = carray_get(msg_tab, i);
98 mailpop3_msg_info_free(msg);
99 }
100 carray_free(msg_tab);
101}
102
103static void mailpop3_msg_info_tab_reset(carray * msg_tab)
104{
105 unsigned int i;
106
107 for(i = 0 ; i < carray_count(msg_tab) ; i++) {
108 struct mailpop3_msg_info * msg;
109 msg = carray_get(msg_tab, i);
110 msg->msg_deleted = FALSE;
111 }
112}
113
114static inline struct mailpop3_msg_info *
115mailpop3_msg_info_tab_find_msg(carray * msg_tab, unsigned int index)
116{
117 struct mailpop3_msg_info * msg;
118
119 if (index == 0)
120 return NULL;
121
122 if (index > carray_count(msg_tab))
123 return NULL;
124
125 msg = carray_get(msg_tab, index - 1);
126
127 return msg;
128}
129
130
131
132int mailpop3_get_msg_info(mailpop3 * f, unsigned int index,
133 struct mailpop3_msg_info ** result)
134{
135 carray * tab;
136 struct mailpop3_msg_info * info;
137
138 mailpop3_list(f, &tab);
139
140 if (tab == NULL)
141 return MAILPOP3_ERROR_BAD_STATE;
142
143 info = mailpop3_msg_info_tab_find_msg(tab, index);
144 if (info == NULL)
145 return MAILPOP3_ERROR_NO_SUCH_MESSAGE;
146
147 * result = info;
148
149 return MAILPOP3_NO_ERROR;
150}
151
152
153/*
154 mailpop3_capa
155*/
156
157struct mailpop3_capa * mailpop3_capa_new(char * name, clist * param)
158{
159 struct mailpop3_capa * capa;
160
161 capa = malloc(sizeof(* capa));
162 if (capa == NULL)
163 return NULL;
164 capa->cap_name = name;
165 capa->cap_param = param;
166
167 return capa;
168}
169
170
171void mailpop3_capa_free(struct mailpop3_capa * capa)
172{
173 clist_foreach(capa->cap_param, (clist_func) free, NULL);
174 clist_free(capa->cap_param);
175 free(capa->cap_name);
176 free(capa);
177}
178
179/*
180 mailpop3 structure
181*/
182
183mailpop3 * mailpop3_new(size_t progr_rate, progress_function * progr_fun)
184{
185 mailpop3 * f;
186
187 f = malloc(sizeof(* f));
188 if (f == NULL)
189 goto err;
190
191 f->pop3_timestamp = NULL;
192 f->pop3_response = NULL;
193
194 f->pop3_stream = NULL;
195
196 f->pop3_progr_rate = progr_rate;
197 f->pop3_progr_fun = progr_fun;
198
199 f->pop3_stream_buffer = mmap_string_new("");
200 if (f->pop3_stream_buffer == NULL)
201 goto free_f;
202
203 f->pop3_response_buffer = mmap_string_new("");
204 if (f->pop3_response_buffer == NULL)
205 goto free_stream_buffer;
206
207 f->pop3_msg_tab = NULL;
208 f->pop3_deleted_count = 0;
209 f->pop3_state = POP3_STATE_DISCONNECTED;
210
211 return f;
212
213 free_stream_buffer:
214 mmap_string_free(f->pop3_stream_buffer);
215 free_f:
216 free(f);
217 err:
218 return NULL;
219}
220
221
222
223void mailpop3_free(mailpop3 * f)
224{
225 if (f->pop3_stream)
226 mailpop3_quit(f);
227
228 mmap_string_free(f->pop3_response_buffer);
229 mmap_string_free(f->pop3_stream_buffer);
230
231 free(f);
232}
233
234
235
236
237
238
239
240
241
242
243
244/*
245 operations on mailpop3 structure
246*/
247
248#define RESPONSE_OK 0
249#define RESPONSE_ERR -1
250
251static int send_command(mailpop3 * f, char * command);
252
253static char * read_line(mailpop3 * f);
254
255static char * read_multiline(mailpop3 * f, size_t size,
256 MMAPString * multiline_buffer);
257
258static int parse_response(mailpop3 * f, char * response);
259
260
261/* get the timestamp in the connection response */
262
263#define TIMESTAMP_START '<'
264#define TIMESTAMP_END '>'
265
266static char * mailpop3_get_timestamp(char * response)
267{
268 char * begin_timestamp;
269 char * end_timestamp;
270 char * timestamp;
271 int len_timestamp;
272
273 if (response == NULL)
274 return NULL;
275
276 begin_timestamp = strchr(response, TIMESTAMP_START);
277
278 end_timestamp = NULL;
279 if (begin_timestamp != NULL) {
280 end_timestamp = strchr(begin_timestamp, TIMESTAMP_END);
281 if (end_timestamp == NULL)
282 begin_timestamp = NULL;
283 }
284
285 if (!begin_timestamp)
286 return NULL;
287
288 len_timestamp = end_timestamp - begin_timestamp + 1;
289
290 timestamp = malloc(len_timestamp + 1);
291 if (timestamp == NULL)
292 return NULL;
293 strncpy(timestamp, begin_timestamp, len_timestamp);
294 timestamp[len_timestamp] = '\0';
295
296 return timestamp;
297}
298
299/*
300 connect a stream to the mailpop3 structure
301*/
302
303int mailpop3_connect(mailpop3 * f, mailstream * s)
304{
305 char * response;
306 int r;
307 char * timestamp;
308
309 if (f->pop3_state != POP3_STATE_DISCONNECTED)
310 return MAILPOP3_ERROR_BAD_STATE;
311
312 f->pop3_stream = s;
313
314 response = read_line(f);
315
316 r = parse_response(f, response);
317 if (r != RESPONSE_OK)
318 return MAILPOP3_ERROR_UNAUTHORIZED;
319
320 f->pop3_state = POP3_STATE_AUTHORIZATION;
321
322 timestamp = mailpop3_get_timestamp(f->pop3_response);
323 if (timestamp != NULL)
324 f->pop3_timestamp = timestamp;
325
326 return MAILPOP3_NO_ERROR;
327}
328
329
330/*
331 disconnect from a pop3 server
332*/
333
334int mailpop3_quit(mailpop3 * f)
335{
336 char command[POP3_STRING_SIZE];
337 char * response;
338 int r;
339 int res;
340
341 if ((f->pop3_state != POP3_STATE_AUTHORIZATION)
342 && (f->pop3_state != POP3_STATE_TRANSACTION)) {
343 res = MAILPOP3_ERROR_BAD_STATE;
344 goto close;
345 }
346
347 snprintf(command, POP3_STRING_SIZE, "QUIT\r\n");
348 r = send_command(f, command);
349 if (r == -1) {
350 res = MAILPOP3_ERROR_STREAM;
351 goto close;
352 }
353
354 response = read_line(f);
355 if (response == NULL) {
356 res = MAILPOP3_ERROR_STREAM;
357 goto close;
358 }
359 parse_response(f, response);
360
361 res = MAILPOP3_NO_ERROR;
362
363 close:
364 mailstream_close(f->pop3_stream);
365
366 if (f->pop3_timestamp != NULL) {
367 free(f->pop3_timestamp);
368 f->pop3_timestamp = NULL;
369 }
370
371 f->pop3_stream = NULL;
372 if (f->pop3_msg_tab != NULL) {
373 mailpop3_msg_info_tab_free(f->pop3_msg_tab);
374 f->pop3_msg_tab = NULL;
375 }
376
377 f->pop3_state = POP3_STATE_DISCONNECTED;
378
379 return res;
380}
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413int mailpop3_apop(mailpop3 * f,
414 const char * user, const char * password)
415{
416 char command[POP3_STRING_SIZE];
417 MD5_CTX md5context;
418 unsigned char md5digest[16];
419 char md5string[33];
420 char * cmd_ptr;
421 int r;
422 int i;
423 char * response;
424
425 if (f->pop3_state != POP3_STATE_AUTHORIZATION)
426 return MAILPOP3_ERROR_BAD_STATE;
427
428 if (f->pop3_timestamp == NULL)
429 return MAILPOP3_ERROR_APOP_NOT_SUPPORTED;
430
431 /* calculate md5 sum */
432
433 MD5Init(&md5context);
434 MD5Update(&md5context, f->pop3_timestamp, strlen (f->pop3_timestamp));
435 MD5Update(&md5context, password, strlen (password));
436 MD5Final(md5digest, &md5context);
437
438 cmd_ptr = md5string;
439 for(i = 0 ; i < 16 ; i++, cmd_ptr += 2)
440 snprintf(cmd_ptr, 3, "%02x", md5digest[i]);
441 * cmd_ptr = 0;
442
443 /* send apop command */
444
445 snprintf(command, POP3_STRING_SIZE, "APOP %s %s\r\n", user, md5string);
446 r = send_command(f, command);
447 if (r == -1)
448 return MAILPOP3_ERROR_STREAM;
449
450 response = read_line(f);
451
452 if (response == NULL)
453 return MAILPOP3_ERROR_STREAM;
454 r = parse_response(f, response);
455 if (r != RESPONSE_OK)
456 return MAILPOP3_ERROR_DENIED;
457
458 f->pop3_state = POP3_STATE_TRANSACTION;
459
460 return MAILPOP3_NO_ERROR;
461}
462
463int mailpop3_user(mailpop3 * f, const char * user)
464{
465 char command[POP3_STRING_SIZE];
466 int r;
467 char * response;
468
469 if (f->pop3_state != POP3_STATE_AUTHORIZATION)
470 return MAILPOP3_ERROR_BAD_STATE;
471
472 /* send user command */
473
474 snprintf(command, POP3_STRING_SIZE, "USER %s\r\n", user);
475 r = send_command(f, command);
476 if (r == -1)
477 return MAILPOP3_ERROR_STREAM;
478
479 response = read_line(f);
480 if (response == NULL)
481 return MAILPOP3_ERROR_STREAM;
482 r = parse_response(f, response);
483
484 if (r != RESPONSE_OK)
485 return MAILPOP3_ERROR_BAD_USER;
486
487 return MAILPOP3_NO_ERROR;
488}
489
490int mailpop3_pass(mailpop3 * f, const char * password)
491{
492 char command[POP3_STRING_SIZE];
493 int r;
494 char * response;
495
496 if (f->pop3_state != POP3_STATE_AUTHORIZATION)
497 return MAILPOP3_ERROR_BAD_STATE;
498
499 /* send password command */
500
501 snprintf(command, POP3_STRING_SIZE, "PASS %s\r\n", password);
502 r = send_command(f, command);
503 if (r == -1)
504 return MAILPOP3_ERROR_STREAM;
505
506 response = read_line(f);
507 if (response == NULL)
508 return MAILPOP3_ERROR_STREAM;
509 r = parse_response(f, response);
510
511 if (r != RESPONSE_OK)
512 return MAILPOP3_ERROR_BAD_PASSWORD;
513
514 f->pop3_state = POP3_STATE_TRANSACTION;
515
516 return MAILPOP3_NO_ERROR;
517}
518
519static int read_list(mailpop3 * f, carray ** result);
520
521
522
523static int read_uidl(mailpop3 * f, carray * msg_tab);
524
525
526
527static int mailpop3_do_uidl(mailpop3 * f, carray * msg_tab)
528{
529 char command[POP3_STRING_SIZE];
530 int r;
531 char * response;
532
533 if (f->pop3_state != POP3_STATE_TRANSACTION)
534 return MAILPOP3_ERROR_BAD_STATE;
535
536 /* send list command */
537
538 snprintf(command, POP3_STRING_SIZE, "UIDL\r\n");
539 r = send_command(f, command);
540 if (r == -1)
541 return MAILPOP3_ERROR_STREAM;
542
543 response = read_line(f);
544 if (response == NULL)
545 return MAILPOP3_ERROR_STREAM;
546 r = parse_response(f, response);
547
548 if (r != RESPONSE_OK)
549 return MAILPOP3_ERROR_CANT_LIST;
550
551 r = read_uidl(f, msg_tab);
552 if (r != MAILPOP3_NO_ERROR)
553 return r;
554
555 return MAILPOP3_NO_ERROR;
556}
557
558
559
560static int mailpop3_do_list(mailpop3 * f)
561{
562 char command[POP3_STRING_SIZE];
563 int r;
564 carray * msg_tab;
565 char * response;
566
567 if (f->pop3_msg_tab != NULL) {
568 mailpop3_msg_info_tab_free(f->pop3_msg_tab);
569 f->pop3_msg_tab = NULL;
570 }
571
572 if (f->pop3_state != POP3_STATE_TRANSACTION)
573 return MAILPOP3_ERROR_BAD_STATE;
574
575 /* send list command */
576
577 snprintf(command, POP3_STRING_SIZE, "LIST\r\n");
578 r = send_command(f, command);
579 if (r == -1)
580 return MAILPOP3_ERROR_STREAM;
581
582 response = read_line(f);
583 if (response == NULL)
584 return MAILPOP3_ERROR_STREAM;
585 r = parse_response(f, response);
586
587 if (r != RESPONSE_OK)
588 return MAILPOP3_ERROR_CANT_LIST;
589
590 r = read_list(f, &msg_tab);
591 if (r != MAILPOP3_NO_ERROR)
592 return r;
593
594 f->pop3_msg_tab = msg_tab;
595 f->pop3_deleted_count = 0;
596
597 mailpop3_do_uidl(f, msg_tab);
598
599 return MAILPOP3_NO_ERROR;
600}
601
602
603
604static void mailpop3_list_if_needed(mailpop3 * f)
605{
606 if (f->pop3_msg_tab == NULL)
607 mailpop3_do_list(f);
608}
609
610/*
611 mailpop3_list
612*/
613
614void mailpop3_list(mailpop3 * f, carray ** result)
615{
616 mailpop3_list_if_needed(f);
617 * result = f->pop3_msg_tab;
618}
619
620static inline struct mailpop3_msg_info *
621find_msg(mailpop3 * f, unsigned int index)
622{
623 mailpop3_list_if_needed(f);
624
625 if (f->pop3_msg_tab == NULL)
626 return NULL;
627
628 return mailpop3_msg_info_tab_find_msg(f->pop3_msg_tab, index);
629}
630
631
632
633
634
635
636
637
638static void mailpop3_multiline_response_free(char * str)
639{
640 mmap_string_unref(str);
641}
642
643void mailpop3_top_free(char * str)
644{
645 mailpop3_multiline_response_free(str);
646}
647
648void mailpop3_retr_free(char * str)
649{
650 mailpop3_multiline_response_free(str);
651}
652
653/*
654 mailpop3_retr
655
656 message content in (* result) is still there until the
657 next retrieve or top operation on the mailpop3 structure
658*/
659
660static int
661mailpop3_get_content(mailpop3 * f, struct mailpop3_msg_info * msginfo,
662 char ** result, size_t * result_len)
663{
664 char * response;
665 char * result_multiline;
666 MMAPString * buffer;
667 int r;
668
669 response = read_line(f);
670 if (response == NULL)
671 return MAILPOP3_ERROR_STREAM;
672 r = parse_response(f, response);
673 if (r != RESPONSE_OK)
674 return MAILPOP3_ERROR_NO_SUCH_MESSAGE;
675
676 buffer = mmap_string_new("");
677 if (buffer == NULL)
678 return MAILPOP3_ERROR_MEMORY;
679
680 result_multiline = read_multiline(f, msginfo->msg_size, buffer);
681 if (result_multiline == NULL) {
682 mmap_string_free(buffer);
683 return MAILPOP3_ERROR_STREAM;
684 }
685 else {
686 r = mmap_string_ref(buffer);
687 if (r < 0) {
688 mmap_string_free(buffer);
689 return MAILPOP3_ERROR_MEMORY;
690 }
691
692 * result = result_multiline;
693 * result_len = buffer->len;
694 return MAILPOP3_NO_ERROR;
695 }
696}
697
698int mailpop3_retr(mailpop3 * f, unsigned int index, char ** result,
699 size_t * result_len)
700{
701 char command[POP3_STRING_SIZE];
702 struct mailpop3_msg_info * msginfo;
703 int r;
704
705 if (f->pop3_state != POP3_STATE_TRANSACTION)
706 return MAILPOP3_ERROR_BAD_STATE;
707
708 msginfo = find_msg(f, index);
709
710 if (msginfo == NULL) {
711 f->pop3_response = NULL;
712 return MAILPOP3_ERROR_NO_SUCH_MESSAGE;
713 }
714
715 snprintf(command, POP3_STRING_SIZE, "RETR %i\r\n", index);
716 r = send_command(f, command);
717 if (r == -1)
718 return MAILPOP3_ERROR_STREAM;
719
720 return mailpop3_get_content(f, msginfo, result, result_len);
721}
722
723int mailpop3_top(mailpop3 * f, unsigned int index,
724 uint32_t count, char ** result,
725 size_t * result_len)
726{
727 char command[POP3_STRING_SIZE];
728 struct mailpop3_msg_info * msginfo;
729 int r;
730
731 if (f->pop3_state != POP3_STATE_TRANSACTION)
732 return MAILPOP3_ERROR_BAD_STATE;
733
734 msginfo = find_msg(f, index);
735
736 if (msginfo == NULL) {
737 f->pop3_response = NULL;
738 return MAILPOP3_ERROR_NO_SUCH_MESSAGE;
739 }
740
741 snprintf(command, POP3_STRING_SIZE, "TOP %i %i\r\n", index, count);
742 r = send_command(f, command);
743 if (r == -1)
744 return MAILPOP3_ERROR_STREAM;
745
746 return mailpop3_get_content(f, msginfo, result, result_len);
747}
748
749int mailpop3_dele(mailpop3 * f, unsigned int index)
750{
751 char command[POP3_STRING_SIZE];
752 struct mailpop3_msg_info * msginfo;
753 char * response;
754 int r;
755
756 if (f->pop3_state != POP3_STATE_TRANSACTION)
757 return MAILPOP3_ERROR_BAD_STATE;
758
759 msginfo = find_msg(f, index);
760
761 if (msginfo == NULL) {
762 f->pop3_response = NULL;
763 return MAILPOP3_ERROR_NO_SUCH_MESSAGE;
764 }
765
766 snprintf(command, POP3_STRING_SIZE, "DELE %i\r\n", index);
767 r = send_command(f, command);
768 if (r == -1)
769 return MAILPOP3_ERROR_STREAM;
770
771 response = read_line(f);
772 if (response == NULL)
773 return MAILPOP3_ERROR_STREAM;
774 r = parse_response(f, response);
775 if (r != RESPONSE_OK)
776 return MAILPOP3_ERROR_NO_SUCH_MESSAGE;
777
778 msginfo->msg_deleted = TRUE;
779 f->pop3_deleted_count ++;
780
781 return MAILPOP3_NO_ERROR;
782}
783
784int mailpop3_noop(mailpop3 * f)
785{
786 char command[POP3_STRING_SIZE];
787 char * response;
788 int r;
789
790 if (f->pop3_state != POP3_STATE_TRANSACTION)
791 return MAILPOP3_ERROR_BAD_STATE;
792
793 snprintf(command, POP3_STRING_SIZE, "NOOP\r\n");
794 r = send_command(f, command);
795 if (r == -1)
796 return MAILPOP3_ERROR_STREAM;
797
798 response = read_line(f);
799 if (response == NULL)
800 return MAILPOP3_ERROR_STREAM;
801 parse_response(f, response);
802
803 return MAILPOP3_NO_ERROR;
804}
805
806int mailpop3_rset(mailpop3 * f)
807{
808 char command[POP3_STRING_SIZE];
809 char * response;
810 int r;
811
812 if (f->pop3_state != POP3_STATE_TRANSACTION)
813 return MAILPOP3_ERROR_BAD_STATE;
814
815 snprintf(command, POP3_STRING_SIZE, "RSET\r\n");
816 r = send_command(f, command);
817 if (r == -1)
818 return MAILPOP3_ERROR_STREAM;
819
820 response = read_line(f);
821 if (response == NULL)
822 return MAILPOP3_ERROR_STREAM;
823 parse_response(f, response);
824
825 if (f->pop3_msg_tab != NULL) {
826 mailpop3_msg_info_tab_reset(f->pop3_msg_tab);
827 f->pop3_deleted_count = 0;
828 }
829
830 return MAILPOP3_NO_ERROR;
831}
832
833
834
835static int read_capa_resp(mailpop3 * f, clist ** result);
836
837int mailpop3_capa(mailpop3 * f, clist ** result)
838{
839 clist * capa_list;
840 char command[POP3_STRING_SIZE];
841 int r;
842 char * response;
843
844 snprintf(command, POP3_STRING_SIZE, "CAPA\r\n");
845 r = send_command(f, command);
846 if (r == -1)
847 return MAILPOP3_ERROR_STREAM;
848
849 response = read_line(f);
850 if (response == NULL)
851 return MAILPOP3_ERROR_STREAM;
852 r = parse_response(f, response);
853
854 if (r != RESPONSE_OK)
855 return MAILPOP3_ERROR_CAPA_NOT_SUPPORTED;
856
857 r = read_capa_resp(f, &capa_list);
858 if (r != MAILPOP3_NO_ERROR)
859 return r;
860
861 * result = capa_list;
862
863 return MAILPOP3_NO_ERROR;
864}
865
866void mailpop3_capa_resp_free(clist * capa_list)
867{
868 clist_foreach(capa_list, (clist_func) mailpop3_capa_free, NULL);
869 clist_free(capa_list);
870}
871
872int mailpop3_stls(mailpop3 * f)
873{
874 char command[POP3_STRING_SIZE];
875 int r;
876 char * response;
877
878 snprintf(command, POP3_STRING_SIZE, "STLS\r\n");
879 r = send_command(f, command);
880 if (r == -1)
881 return MAILPOP3_ERROR_STREAM;
882
883 response = read_line(f);
884 if (response == NULL)
885 return MAILPOP3_ERROR_STREAM;
886 r = parse_response(f, response);
887
888 if (r != RESPONSE_OK)
889 return MAILPOP3_ERROR_STLS_NOT_SUPPORTED;
890
891 return MAILPOP3_NO_ERROR;
892}
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917#define RESP_OK_STR "+OK"
918#define RESP_ERR_STR "-ERR"
919
920
921static int parse_space(char ** line)
922{
923 char * p;
924
925 p = * line;
926
927 while ((* p == ' ') || (* p == '\t'))
928 p ++;
929
930 if (p != * line) {
931 * line = p;
932 return TRUE;
933 }
934 else
935 return FALSE;
936}
937
938static char * cut_token(char * line)
939{
940 char * p;
941 char * p_tab;
942 char * p_space;
943
944 p = line;
945
946 p_space = strchr(line, ' ');
947 p_tab = strchr(line, '\t');
948 if (p_tab == NULL)
949 p = p_space;
950 else if (p_space == NULL)
951 p = p_tab;
952 else {
953 if (p_tab < p_space)
954 p = p_tab;
955 else
956 p = p_space;
957 }
958 if (p == NULL)
959 return NULL;
960 * p = 0;
961 p ++;
962
963 return p;
964}
965
966
967static int parse_response(mailpop3 * f, char * response)
968{
969 char * msg;
970
971 if (response == NULL) {
972 f->pop3_response = NULL;
973 return RESPONSE_ERR;
974 }
975
976 if (strncmp(response, RESP_OK_STR, strlen(RESP_OK_STR)) == 0) {
977
978 if (response[strlen(RESP_OK_STR)] == ' ')
979 msg = response + strlen(RESP_OK_STR) + 1;
980 else
981 msg = response + strlen(RESP_OK_STR);
982
983 if (mmap_string_assign(f->pop3_response_buffer, msg))
984 f->pop3_response = f->pop3_response_buffer->str;
985 else
986 f->pop3_response = NULL;
987
988 return RESPONSE_OK;
989 }
990 else if (strncmp(response, RESP_ERR_STR, strlen(RESP_ERR_STR)) == 0) {
991
992 if (response[strlen(RESP_ERR_STR)] == ' ')
993 msg = response + strlen(RESP_ERR_STR) + 1;
994 else
995 msg = response + strlen(RESP_ERR_STR);
996
997 if (mmap_string_assign(f->pop3_response_buffer, msg))
998 f->pop3_response = f->pop3_response_buffer->str;
999 else
1000 f->pop3_response = NULL;
1001 }
1002
1003 f->pop3_response = NULL;
1004 return RESPONSE_ERR;
1005}
1006
1007
1008
1009
1010
1011
1012
1013static int read_list(mailpop3 * f, carray ** result)
1014{
1015 unsigned int index;
1016 uint32_t size;
1017 carray * msg_tab;
1018 struct mailpop3_msg_info * msg;
1019 char * line;
1020
1021 msg_tab = carray_new(128);
1022 if (msg_tab == NULL)
1023 goto err;
1024
1025 while (1) {
1026 line = read_line(f);
1027 if (line == NULL)
1028 goto free_list;
1029
1030 if (mailstream_is_end_multiline(line))
1031 break;
1032
1033 index = strtol(line, &line, 10);
1034
1035 if (!parse_space(&line))
1036 continue;
1037
1038 size = strtol(line, &line, 10);
1039
1040 msg = mailpop3_msg_info_new(index, size, NULL);
1041 if (msg == NULL)
1042 goto free_list;
1043
1044 if (carray_count(msg_tab) < index) {
1045 int r;
1046
1047 r = carray_set_size(msg_tab, index);
1048 if (r == -1)
1049 goto free_list;
1050 }
1051
1052 carray_set(msg_tab, index - 1, msg);
1053 }
1054
1055 * result = msg_tab;
1056
1057 return MAILPOP3_NO_ERROR;
1058
1059 free_list:
1060 mailpop3_msg_info_tab_free(msg_tab);
1061 err:
1062 return MAILPOP3_ERROR_STREAM;
1063}
1064
1065
1066
1067static int read_uidl(mailpop3 * f, carray * msg_tab)
1068{
1069 unsigned int index;
1070 struct mailpop3_msg_info * msg;
1071 char * line;
1072
1073 while (1) {
1074 char * uidl;
1075
1076 line = read_line(f);
1077 if (line == NULL)
1078 goto err;
1079
1080 if (mailstream_is_end_multiline(line))
1081 break;
1082
1083 index = strtol(line, &line, 10);
1084
1085 if (!parse_space(&line))
1086 continue;
1087
1088 uidl = strdup(line);
1089 if (uidl == NULL)
1090 continue;
1091
1092 if (index > carray_count(msg_tab)) {
1093 free(uidl);
1094 continue;
1095 }
1096
1097 msg = carray_get(msg_tab, index - 1);
1098 if (msg == NULL) {
1099 free(uidl);
1100 continue;
1101 }
1102
1103 msg->msg_uidl = uidl;
1104 }
1105
1106 return MAILPOP3_NO_ERROR;
1107
1108 err:
1109 return MAILPOP3_ERROR_STREAM;
1110}
1111
1112
1113
1114static int read_capa_resp(mailpop3 * f, clist ** result)
1115{
1116 char * line;
1117 int res;
1118 clist * list;
1119 int r;
1120 char * name;
1121 clist * param_list;
1122
1123 list = clist_new();
1124 if (list == NULL) {
1125 res = MAILPOP3_NO_ERROR;
1126 goto err;
1127 }
1128
1129 while (1) {
1130 char * next_token;
1131 char * param;
1132 struct mailpop3_capa * capa;
1133
1134 line = read_line(f);
1135 if (line == NULL) {
1136 res = MAILPOP3_ERROR_STREAM;
1137 goto free_list;
1138 }
1139
1140 if (mailstream_is_end_multiline(line))
1141 break;
1142
1143 next_token = cut_token(line);
1144 name = strdup(line);
1145 if (name == NULL) {
1146 res = MAILPOP3_ERROR_MEMORY;
1147 goto free_list;
1148 }
1149
1150 param_list = clist_new();
1151 if (param_list == NULL) {
1152 res = MAILPOP3_ERROR_MEMORY;
1153 goto free_capa_name;
1154 }
1155
1156 while (next_token != NULL) {
1157 line = next_token;
1158 next_token = cut_token(line);
1159 param = strdup(line);
1160 if (param == NULL) {
1161 res = MAILPOP3_ERROR_MEMORY;
1162 goto free_param_list;
1163 }
1164 r = clist_append(param_list, param);
1165 if (r < 0) {
1166 free(param);
1167 res = MAILPOP3_ERROR_MEMORY;
1168 goto free_param_list;
1169 }
1170 }
1171
1172 capa = mailpop3_capa_new(name, param_list);
1173 if (capa == NULL) {
1174 res = MAILPOP3_ERROR_MEMORY;
1175 goto free_param_list;
1176 }
1177
1178 r = clist_append(list, capa);
1179 if (r < 0) {
1180 mailpop3_capa_free(capa);
1181 res = MAILPOP3_ERROR_MEMORY;
1182 goto free_list;
1183 }
1184 }
1185
1186 * result = list;
1187
1188 return MAILPOP3_NO_ERROR;
1189
1190 free_param_list:
1191 clist_foreach(param_list, (clist_func) free, NULL);
1192 clist_free(param_list);
1193 free_capa_name:
1194 free(name);
1195 free_list:
1196 clist_foreach(list, (clist_func) mailpop3_capa_free, NULL);
1197 clist_free(list);
1198 err:
1199 return res;
1200}
1201
1202
1203
1204static char * read_line(mailpop3 * f)
1205{
1206 return mailstream_read_line_remove_eol(f->pop3_stream, f->pop3_stream_buffer);
1207}
1208
1209static char * read_multiline(mailpop3 * f, size_t size,
1210 MMAPString * multiline_buffer)
1211{
1212 return mailstream_read_multiline(f->pop3_stream, size,
1213 f->pop3_stream_buffer, multiline_buffer,
1214 f->pop3_progr_rate, f->pop3_progr_fun);
1215}
1216
1217static int send_command(mailpop3 * f, char * command)
1218{
1219 ssize_t r;
1220
1221 r = mailstream_write(f->pop3_stream, command, strlen(command));
1222 if (r == -1)
1223 return -1;
1224
1225 r = mailstream_flush(f->pop3_stream);
1226 if (r == -1)
1227 return -1;
1228
1229 return 0;
1230}
diff --git a/kmicromail/libetpan/pop3/mailpop3.h b/kmicromail/libetpan/pop3/mailpop3.h
new file mode 100644
index 0000000..b8552ab
--- a/dev/null
+++ b/kmicromail/libetpan/pop3/mailpop3.h
@@ -0,0 +1,100 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILPOP3_H
37
38#define MAILPOP3_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailpop3_types.h>
45
46#include <libetpan/mailpop3_helper.h>
47
48#include <libetpan/mailpop3_socket.h>
49#include <libetpan/mailpop3_ssl.h>
50
51#define POP3_STRING_SIZE 513
52
53mailpop3 * mailpop3_new(size_t pop3_progr_rate,
54 progress_function * pop3_progr_fun);
55
56void mailpop3_free(mailpop3 * f);
57
58int mailpop3_connect(mailpop3 * f, mailstream * s);
59
60int mailpop3_quit(mailpop3 * f);
61
62
63int mailpop3_apop(mailpop3 * f, const char * user, const char * password);
64
65int mailpop3_user(mailpop3 * f, const char * user);
66
67int mailpop3_pass(mailpop3 * f, const char * password);
68
69void mailpop3_list(mailpop3 * f, carray ** result);
70
71int mailpop3_retr(mailpop3 * f, uint32_t index, char ** result,
72 size_t * result_len);
73
74int mailpop3_top(mailpop3 * f, uint32_t index, uint32_t count,
75 char ** result, size_t * result_len);
76
77int mailpop3_dele(mailpop3 * f, uint32_t index);
78
79int mailpop3_noop(mailpop3 * f);
80
81int mailpop3_rset(mailpop3 * f);
82
83void mailpop3_top_free(char * str);
84
85void mailpop3_retr_free(char * str);
86
87int mailpop3_get_msg_info(mailpop3 * f, uint32_t index,
88 struct mailpop3_msg_info ** result);
89
90int mailpop3_capa(mailpop3 * f, clist ** result);
91
92void mailpop3_capa_resp_free(clist * capa_list);
93
94int mailpop3_stls(mailpop3 * f);
95
96#ifdef __cplusplus
97}
98#endif
99
100#endif
diff --git a/kmicromail/libetpan/pop3/mailpop3_helper.c b/kmicromail/libetpan/pop3/mailpop3_helper.c
new file mode 100644
index 0000000..5a3c26b
--- a/dev/null
+++ b/kmicromail/libetpan/pop3/mailpop3_helper.c
@@ -0,0 +1,78 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailpop3_helper.h"
37
38#include <string.h>
39
40int mailpop3_login_apop(mailpop3 * f,
41 char * user,
42 char * password)
43{
44 return mailpop3_apop(f, user, password);
45}
46
47
48/*
49 mailpop3_login
50
51 must be used immediately after connect
52*/
53
54int mailpop3_login(mailpop3 * f,
55 char * user,
56 char * password)
57{
58 int r;
59
60 if ((r = mailpop3_user(f, user)) != MAILPOP3_NO_ERROR)
61 return r;
62
63 if ((r = mailpop3_pass(f, password)) != MAILPOP3_NO_ERROR)
64 return r;
65
66 return MAILPOP3_NO_ERROR;
67}
68
69void mailpop3_header_free(char * str)
70{
71 mailpop3_top_free(str);
72}
73
74int mailpop3_header(mailpop3 * f, uint32_t index, char ** result,
75 size_t * result_len)
76{
77 return mailpop3_top(f, index, 0, result, result_len);
78}
diff --git a/kmicromail/libetpan/pop3/mailpop3_helper.h b/kmicromail/libetpan/pop3/mailpop3_helper.h
new file mode 100644
index 0000000..7337ad8
--- a/dev/null
+++ b/kmicromail/libetpan/pop3/mailpop3_helper.h
@@ -0,0 +1,64 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILPOP3_HELPER_H
37
38#define MAILPOP3_HELPER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mailpop3.h"
45
46int mailpop3_login_apop(mailpop3 * f,
47 char * user,
48 char * password);
49
50int mailpop3_login(mailpop3 * f,
51 char * user,
52 char * password);
53
54int mailpop3_header(mailpop3 * f, uint32_t index, char ** result,
55 size_t * result_len);
56
57void mailpop3_header_free(char * str);
58
59#ifdef __cplusplus
60}
61#endif
62
63#endif
64
diff --git a/kmicromail/libetpan/pop3/mailpop3_socket.c b/kmicromail/libetpan/pop3/mailpop3_socket.c
new file mode 100644
index 0000000..3897969
--- a/dev/null
+++ b/kmicromail/libetpan/pop3/mailpop3_socket.c
@@ -0,0 +1,73 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailpop3_socket.h"
37
38#include "mailpop3.h"
39
40#include "connect.h"
41#include <netinet/in.h>
42#include <unistd.h>
43
44#define DEFAULT_POP3_PORT 110
45#define SERVICE_NAME_POP3 "pop3"
46#define SERVICE_TYPE_TCP "tcp"
47
48int mailpop3_socket_connect(mailpop3 * f, const char * server, uint16_t port)
49{
50 int s;
51 mailstream * stream;
52
53 if (port == 0) {
54 port = mail_get_service_port(SERVICE_NAME_POP3, SERVICE_TYPE_TCP);
55 if (port == 0)
56 port = DEFAULT_POP3_PORT;
57 port = ntohs(port);
58 }
59
60 /* Connection */
61
62 s = mail_tcp_connect(server, port);
63 if (s == -1)
64 return MAILPOP3_ERROR_CONNECTION_REFUSED;
65
66 stream = mailstream_socket_open(s);
67 if (stream == NULL) {
68 close(s);
69 return MAILPOP3_ERROR_MEMORY;
70 }
71
72 return mailpop3_connect(f, stream);
73}
diff --git a/kmicromail/libetpan/pop3/mailpop3_socket.h b/kmicromail/libetpan/pop3/mailpop3_socket.h
new file mode 100644
index 0000000..06f16f5
--- a/dev/null
+++ b/kmicromail/libetpan/pop3/mailpop3_socket.h
@@ -0,0 +1,54 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILPOP3_SOCKET_H
37
38#define MAILPOP3_SOCKET_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45
46#include <libetpan/mailpop3_types.h>
47
48int mailpop3_socket_connect(mailpop3 * f, const char * server, uint16_t port);
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/kmicromail/libetpan/pop3/mailpop3_ssl.c b/kmicromail/libetpan/pop3/mailpop3_ssl.c
new file mode 100644
index 0000000..8fbbcf2
--- a/dev/null
+++ b/kmicromail/libetpan/pop3/mailpop3_ssl.c
@@ -0,0 +1,73 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailpop3_ssl.h"
37
38#include "mailpop3.h"
39
40#include "connect.h"
41#include <netinet/in.h>
42#include <unistd.h>
43
44#define DEFAULT_POP3S_PORT 995
45#define SERVICE_NAME_POP3S "pop3s"
46#define SERVICE_TYPE_TCP "tcp"
47
48int mailpop3_ssl_connect(mailpop3 * f, const char * server, uint16_t port)
49{
50 int s;
51 mailstream * stream;
52
53 if (port == 0) {
54 port = mail_get_service_port(SERVICE_NAME_POP3S, SERVICE_TYPE_TCP);
55 if (port == 0)
56 port = DEFAULT_POP3S_PORT;
57 port = ntohs(port);
58 }
59
60 /* Connection */
61
62 s = mail_tcp_connect(server, port);
63 if (s == -1)
64 return MAILPOP3_ERROR_CONNECTION_REFUSED;
65
66 stream = mailstream_ssl_open(s);
67 if (stream == NULL) {
68 close(s);
69 return MAILPOP3_ERROR_CONNECTION_REFUSED;
70 }
71
72 return mailpop3_connect(f, stream);
73}
diff --git a/kmicromail/libetpan/pop3/mailpop3_ssl.h b/kmicromail/libetpan/pop3/mailpop3_ssl.h
new file mode 100644
index 0000000..926001c
--- a/dev/null
+++ b/kmicromail/libetpan/pop3/mailpop3_ssl.h
@@ -0,0 +1,54 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILPOP3_SSL_H
37
38#define MAILPOP3_SSL_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45
46#include <libetpan/mailpop3_types.h>
47
48int mailpop3_ssl_connect(mailpop3 * f, const char * server, uint16_t port);
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/kmicromail/libetpan/pop3/mailpop3_types.h b/kmicromail/libetpan/pop3/mailpop3_types.h
new file mode 100644
index 0000000..20500f6
--- a/dev/null
+++ b/kmicromail/libetpan/pop3/mailpop3_types.h
@@ -0,0 +1,107 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILPOP3_TYPES_H
37
38#define MAILPOP3_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailstream.h>
45#include <libetpan/mmapstring.h>
46#include <libetpan/carray.h>
47#include <libetpan/clist.h>
48
49#include <inttypes.h>
50
51enum {
52 MAILPOP3_NO_ERROR = 0,
53 MAILPOP3_ERROR_BAD_STATE,
54 MAILPOP3_ERROR_UNAUTHORIZED,
55 MAILPOP3_ERROR_STREAM,
56 MAILPOP3_ERROR_DENIED,
57 MAILPOP3_ERROR_BAD_USER,
58 MAILPOP3_ERROR_BAD_PASSWORD,
59 MAILPOP3_ERROR_CANT_LIST,
60 MAILPOP3_ERROR_NO_SUCH_MESSAGE,
61 MAILPOP3_ERROR_MEMORY,
62 MAILPOP3_ERROR_CONNECTION_REFUSED,
63 MAILPOP3_ERROR_APOP_NOT_SUPPORTED,
64 MAILPOP3_ERROR_CAPA_NOT_SUPPORTED,
65 MAILPOP3_ERROR_STLS_NOT_SUPPORTED,
66};
67
68struct mailpop3
69{
70 char * pop3_response; /* response message */
71 char * pop3_timestamp; /* connection timestamp */
72
73 /* internals */
74 mailstream * pop3_stream;
75 size_t pop3_progr_rate;
76 progress_function * pop3_progr_fun;
77
78 MMAPString * pop3_stream_buffer; /* buffer for lines reading */
79 MMAPString * pop3_response_buffer; /* buffer for responses */
80
81 carray * pop3_msg_tab; /* list of pop3_msg_info structures */
82 int pop3_state; /* state */
83
84 unsigned int pop3_deleted_count;
85};
86
87typedef struct mailpop3 mailpop3;
88
89struct mailpop3_msg_info
90{
91 unsigned int msg_index;
92 uint32_t msg_size;
93 char * msg_uidl;
94 int msg_deleted;
95};
96
97
98struct mailpop3_capa {
99 char * cap_name;
100 clist * cap_param; /* (char *) */
101};
102
103#ifdef __cplusplus
104}
105#endif
106
107#endif
diff --git a/kmicromail/libetpan/smtp/.libs/libmailsmtp.a b/kmicromail/libetpan/smtp/.libs/libmailsmtp.a
new file mode 100644
index 0000000..b856a73
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/.libs/libmailsmtp.a
Binary files differ
diff --git a/kmicromail/libetpan/smtp/TODO b/kmicromail/libetpan/smtp/TODO
new file mode 100644
index 0000000..96f44c6
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/TODO
@@ -0,0 +1 @@
- STARTTLS
diff --git a/kmicromail/libetpan/smtp/mailsmtp.c b/kmicromail/libetpan/smtp/mailsmtp.c
new file mode 100644
index 0000000..b3be432
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp.c
@@ -0,0 +1,982 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa,
5 * All rights reserved.
6 *
7 * SMTP AUTH support by Juergen Graf
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the libEtPan! project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34/*
35 * $Id$
36 */
37
38#include "mailsmtp.h"
39#include "connect.h"
40#include "md5.h"
41#include "base64.h"
42#include "mail.h"
43
44#include <netinet/in.h>
45#include <string.h>
46#include <stdlib.h>
47#include <unistd.h>
48#include <stdio.h>
49
50
51/*
52 RFC 2821 : SMTP
53 RFC 1891 : SMTP Service Extension for Delivery Status Notifications
54
55 RFC 1428 : Transition of Internet Mail from Just-Send-8 to 8bit-SMTP/MIME
56 RFC 1652 : SMTP Service Extension for 8bit-MIMEtransport
57 RFC 1845 : SMTP Service Extension for Checkpoint/Restart
58 RFC 1846 : SMTP 521 Reply Code
59 RFC 1870 : SMTP Service Extension for Message Size Declaration
60 RFC 1985 : SMTP Service Extension for Remote Message Queue Starting
61 RFC 2034 : SMTP Service Extension for Returning Enhanced Error Codes
62 RFC 2442 : The Batch SMTP Media Type
63 RFC 2487 : SMTP Service Extension for Secure SMTP over TLS
64 RFC 2505 : Anti-Spam Recommendations for SMTP MTAs
65 RFC 2554 : SMTP Service Extension for Authentication
66 RFC 2645 : ON-DEMAND MAIL RELAY (ODMR) SMTP with Dynamic IP Addresses
67 RFC 2852 : Deliver By SMTP Service Extension
68 RFC 2920 : SMTP Service Extension for Command Pipelining
69 RFC 3030 : SMTP Service Extensions for Transmission of Large and Binary MIME
70 Messages
71*/
72
73#define SMTP_STATUS_CONTINUE 0x1000
74
75mailsmtp * mailsmtp_new(size_t progr_rate,
76 progress_function * progr_fun)
77{
78 mailsmtp * session;
79
80 session = malloc(sizeof(* session));
81 if (session == NULL)
82 goto err;
83
84 session->stream = NULL;
85
86 session->progr_rate = progr_rate;
87 session->progr_fun = progr_fun;
88
89 session->response = NULL;
90
91 session->line_buffer = mmap_string_new("");
92 if (session->line_buffer == NULL)
93 goto free_session;
94
95 session->response_buffer = mmap_string_new("");
96 if (session->response_buffer == NULL)
97 goto free_line_buffer;
98
99 session->esmtp = 0;
100 session->auth = MAILSMTP_AUTH_NOT_CHECKED;
101
102 return session;
103
104 free_line_buffer:
105 mmap_string_free(session->line_buffer);
106 free_session:
107 free(session);
108 err:
109 return NULL;
110}
111
112void mailsmtp_free(mailsmtp * session)
113{
114 if (session->stream)
115 mailsmtp_quit(session);
116
117 mmap_string_free(session->line_buffer);
118 mmap_string_free(session->response_buffer);
119 free(session);
120}
121
122static int send_command(mailsmtp * f, char * command);
123
124static int read_response(mailsmtp * session);
125
126/* smtp operations */
127
128int mailsmtp_connect(mailsmtp * session, mailstream * s)
129{
130 int code;
131
132 session->stream = s;
133
134 code = read_response(session);
135
136 switch (code) {
137 case 220:
138 return MAILSMTP_NO_ERROR;
139
140 case 554:
141 session->stream = NULL;
142 mailstream_close(s);
143 return MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE;
144
145 default:
146 session->stream = NULL;
147 mailstream_close(s);
148 return MAILSMTP_ERROR_UNEXPECTED_CODE;
149 }
150}
151
152
153#define SMTP_STRING_SIZE 513
154
155int mailsmtp_quit(mailsmtp * session)
156{
157 char command[SMTP_STRING_SIZE];
158 int r;
159
160 snprintf(command, SMTP_STRING_SIZE, "QUIT\r\n");
161 r = send_command(session, command);
162 if (r == -1)
163 return MAILSMTP_ERROR_STREAM;
164 r = read_response(session);
165 if (r == 0)
166 return MAILSMTP_ERROR_STREAM;
167 mailstream_close(session->stream);
168 session->stream = NULL;
169
170 return MAILSMTP_NO_ERROR;
171}
172
173
174
175#define HOSTNAME_SIZE 256
176
177int mailsmtp_helo(mailsmtp * session)
178{
179 int r;
180 char hostname[HOSTNAME_SIZE];
181 char command[SMTP_STRING_SIZE];
182
183 r = gethostname(hostname, HOSTNAME_SIZE);
184 if (r < 0)
185 return MAILSMTP_ERROR_HOSTNAME;
186
187 snprintf(command, SMTP_STRING_SIZE, "HELO %s\r\n", hostname);
188 r = send_command(session, command);
189 if (r == -1)
190 return MAILSMTP_ERROR_STREAM;
191 r = read_response(session);
192
193 switch (r) {
194 case 250:
195 return MAILSMTP_NO_ERROR;
196
197 case 504:
198 return MAILSMTP_ERROR_NOT_IMPLEMENTED;
199
200 case 550:
201 return MAILSMTP_ERROR_ACTION_NOT_TAKEN;
202
203 case 0:
204 return MAILSMTP_ERROR_STREAM;
205
206 default:
207 return MAILSMTP_ERROR_UNEXPECTED_CODE;
208 }
209}
210
211int mailsmtp_mail(mailsmtp * session, const char * from)
212{
213 int r;
214 char command[SMTP_STRING_SIZE];
215
216 snprintf(command, SMTP_STRING_SIZE, "MAIL FROM:<%s>\r\n", from);
217 r = send_command(session, command);
218 if (r == -1)
219 return MAILSMTP_ERROR_STREAM;
220 r = read_response(session);
221
222 switch (r) {
223 case 250:
224 return MAILSMTP_NO_ERROR;
225
226 case 552:
227 return MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION;
228
229 case 451:
230 return MAILSMTP_ERROR_IN_PROCESSING;
231
232 case 452:
233 return MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE;
234
235 case 550:
236 return MAILSMTP_ERROR_MAILBOX_UNAVAILABLE;
237
238 case 553:
239 return MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED;
240
241 case 503:
242 return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND;
243
244 case 0:
245 return MAILSMTP_ERROR_STREAM;
246
247 default:
248 return MAILSMTP_ERROR_UNEXPECTED_CODE;
249 }
250}
251
252int mailsmtp_rcpt(mailsmtp * session, const char * to)
253{
254 return mailesmtp_rcpt(session, to, 0, NULL);
255}
256
257int mailsmtp_data(mailsmtp * session)
258{
259 int r;
260 char command[SMTP_STRING_SIZE];
261
262 snprintf(command, SMTP_STRING_SIZE, "DATA\r\n");
263 r = send_command(session, command);
264 if (r == -1)
265 return MAILSMTP_ERROR_STREAM;
266 r = read_response(session);
267
268 switch (r) {
269 case 354:
270 return MAILSMTP_NO_ERROR;
271
272 case 451:
273 return MAILSMTP_ERROR_IN_PROCESSING;
274
275 case 554:
276 return MAILSMTP_ERROR_TRANSACTION_FAILED;
277
278 case 503:
279 return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND;
280
281 default:
282 return MAILSMTP_ERROR_UNEXPECTED_CODE;
283 }
284}
285
286static int send_data(mailsmtp * session, const char * message, size_t size);
287
288int mailsmtp_data_message(mailsmtp * session,
289 const char * message,
290 size_t size)
291{
292 int r;
293
294 r = send_data(session, message, size);
295 if (r == -1)
296 return MAILSMTP_ERROR_STREAM;
297
298 r = read_response(session);
299
300 switch(r) {
301 case 250:
302 return MAILSMTP_NO_ERROR;
303
304 case 552:
305 return MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION;
306
307 case 554:
308 return MAILSMTP_ERROR_TRANSACTION_FAILED;
309
310 case 451:
311 return MAILSMTP_ERROR_IN_PROCESSING;
312
313 case 452:
314 return MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE;
315
316 case 0:
317 return MAILSMTP_ERROR_STREAM;
318
319 default:
320 return MAILSMTP_ERROR_UNEXPECTED_CODE;
321 }
322}
323
324/* esmtp operations */
325
326
327/**
328 * called during mailesmtp_ehlo
329 * checks EHLO answer for server extensions and sets flags
330 * in session->esmtp
331 * checks AUTH methods in session->response and sets flags
332 * in session->auth
333 */
334#define isdelim(x) ((x) == ' ' || (x) == '\r' || (x) == '\n' || (x) == '\0')
335
336int mailesmtp_parse_ehlo(mailsmtp * session)
337{
338 char * response;
339
340 /* restore data */
341 session->esmtp = MAILSMTP_ESMTP;
342 session->auth = MAILSMTP_AUTH_CHECKED;
343
344 response = session->response;
345
346 /* ESMTP supported extensions :
347 DSN
348 EXPN
349 8BITMIME
350 SIZE [<n>]
351 ETRN
352 STARTTLS
353 AUTH <mechanisms...>
354 */
355 while (response != NULL) {
356 if (!strncasecmp(response, "EXPN", 4) && isdelim(response[4]))
357 session->esmtp |= MAILSMTP_ESMTP_EXPN;
358 else if (!strncasecmp(response, "ETRN", 4) && isdelim(response[4]))
359 session->esmtp |= MAILSMTP_ESMTP_ETRN;
360 else if (!strncasecmp(response, "DSN", 3) && isdelim(response[3]))
361 session->esmtp |= MAILSMTP_ESMTP_DSN;
362 else if (!strncasecmp(response, "8BITMIME", 8) && isdelim(response[8]))
363 session->esmtp |= MAILSMTP_ESMTP_8BITMIME;
364 else if (!strncasecmp(response, "STARTTLS", 8) && isdelim(response[8]))
365 session->esmtp |= MAILSMTP_ESMTP_STARTTLS;
366 else if (!strncasecmp(response, "SIZE", 4) && isdelim(response[4])) {
367 session->esmtp |= MAILSMTP_ESMTP_SIZE;
368 /* TODO: grab optionnal max size */
369 } else if (!strncasecmp(response, "AUTH ", 5)) {
370 response += 5; /* remove "AUTH " */
371 while (response[0] != '\n' && response[0] != '\0') {
372 while (response[0] == ' ') response++;
373 if (strncasecmp(response, "LOGIN", 5) == 0) {
374 session->auth |= MAILSMTP_AUTH_LOGIN;
375 response += 5;
376 } else if (strncasecmp(response, "CRAM-MD5", 8) == 0) {
377 session->auth |= MAILSMTP_AUTH_CRAM_MD5;
378 response += 8;
379 } else if (strncasecmp(response, "PLAIN", 5) == 0) {
380 session->auth |= MAILSMTP_AUTH_PLAIN;
381 response += 5;
382 } else {
383 /* unknown auth method - jump to next word or eol */
384 while (!isdelim(response[0]) || response[0] == '\r')
385 response++;
386 }
387 }
388 }
389 response = strpbrk(response, "\n");
390 if (response != NULL)
391 response++;
392 }
393
394 return MAILSMTP_NO_ERROR;
395}
396
397
398int mailesmtp_ehlo(mailsmtp * session)
399{
400 int r;
401 char hostname[HOSTNAME_SIZE];
402 char command[SMTP_STRING_SIZE];
403
404 r = gethostname(hostname, HOSTNAME_SIZE);
405 if (r != 0)
406 return MAILSMTP_ERROR_HOSTNAME;
407
408 snprintf(command, SMTP_STRING_SIZE, "EHLO %s\r\n", hostname);
409 r = send_command(session, command);
410 if (r == -1)
411 return MAILSMTP_ERROR_STREAM;
412 r = read_response(session);
413
414 switch (r) {
415 case 250:
416 return mailesmtp_parse_ehlo(session);
417
418 case 504:
419 return MAILSMTP_ERROR_NOT_IMPLEMENTED;
420
421 case 550:
422 return MAILSMTP_ERROR_ACTION_NOT_TAKEN;
423
424 case 0:
425 return MAILSMTP_ERROR_STREAM;
426
427 default:
428 return MAILSMTP_ERROR_UNEXPECTED_CODE;
429 }
430}
431
432/*
433 if return_full is TRUE, the entire message is returned on error
434 envid can be NULL
435*/
436
437
438int mailesmtp_mail(mailsmtp * session,
439 const char * from,
440 int return_full,
441 const char * envid)
442{
443 int r;
444 char command[SMTP_STRING_SIZE];
445 char *body = "";
446
447#if notyet
448 /* TODO: figure out a way for the user to explicity enable this or not */
449 if (session->esmtp & MAILSMTP_ESMTP_8BITMIME)
450 body = " BODY=8BITMIME";
451#endif
452
453 if (session->esmtp & MAILSMTP_ESMTP_DSN) {
454 if (envid)
455 snprintf(command, SMTP_STRING_SIZE, "MAIL FROM:<%s> RET=%s ENVID=%s%s\r\n",
456 from, return_full ? "FULL" : "HDRS", envid, body);
457 else
458 snprintf(command, SMTP_STRING_SIZE, "MAIL FROM:<%s> RET=%s%s\r\n",
459 from, return_full ? "FULL" : "HDRS", body);
460 } else
461 snprintf(command, SMTP_STRING_SIZE, "MAIL FROM:<%s>%s\r\n",
462 from, body);
463
464 r = send_command(session, command);
465 if (r == -1)
466 return MAILSMTP_ERROR_STREAM;
467 r = read_response(session);
468
469 switch (r) {
470 case 250:
471 return MAILSMTP_NO_ERROR;
472
473 case 552:
474 return MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION;
475
476 case 451:
477 return MAILSMTP_ERROR_IN_PROCESSING;
478
479 case 452:
480 return MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE;
481
482 case 550:
483 return MAILSMTP_ERROR_MAILBOX_UNAVAILABLE;
484
485 case 553:
486 return MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED;
487
488 case 503:
489 return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND;
490
491 case 0:
492 return MAILSMTP_ERROR_STREAM;
493
494 default:
495 return MAILSMTP_ERROR_UNEXPECTED_CODE;
496 }
497}
498
499int mailesmtp_rcpt(mailsmtp * session,
500 const char * to,
501 int notify,
502 const char * orcpt)
503{
504 int r;
505 char command[SMTP_STRING_SIZE];
506 char notify_str[30] = "";
507 char notify_info_str[30] = "";
508
509 if (notify != 0 && session->esmtp & MAILSMTP_ESMTP_DSN) {
510 if (notify & MAILSMTP_DSN_NOTIFY_SUCCESS)
511 strcat(notify_info_str, ",SUCCESS");
512 if (notify & MAILSMTP_DSN_NOTIFY_FAILURE)
513 strcat(notify_info_str, ",FAILURE");
514 if (notify & MAILSMTP_DSN_NOTIFY_DELAY)
515 strcat(notify_info_str, ",DELAY");
516
517 if (notify & MAILSMTP_DSN_NOTIFY_NEVER)
518 strcpy(notify_info_str, ",NEVER");
519
520 notify_info_str[0] = '=';
521
522 strcpy(notify_str, " NOTIFY");
523 strcat(notify_str, notify_info_str);
524 }
525
526 if (orcpt && session->esmtp & MAILSMTP_ESMTP_DSN)
527 snprintf(command, SMTP_STRING_SIZE, "RCPT TO:<%s>%s ORCPT=%s\r\n",
528 to, notify_str, orcpt);
529 else
530 snprintf(command, SMTP_STRING_SIZE, "RCPT TO:<%s>%s\r\n", to, notify_str);
531
532 r = send_command(session, command);
533 if (r == -1)
534 return MAILSMTP_ERROR_STREAM;
535 r = read_response(session);
536
537 switch (r) {
538 case 250:
539 return MAILSMTP_NO_ERROR;
540
541 case 251: /* not local user, will be forwarded */
542 return MAILSMTP_NO_ERROR;
543
544 case 550:
545 case 450:
546 return MAILSMTP_ERROR_MAILBOX_UNAVAILABLE;
547
548 case 551:
549 return MAILSMTP_ERROR_USER_NOT_LOCAL;
550
551 case 552:
552 return MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION;
553
554 case 553:
555 return MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED;
556
557 case 451:
558 return MAILSMTP_ERROR_IN_PROCESSING;
559
560 case 452:
561 return MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE;
562
563 case 503:
564 return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND;
565
566 case 0:
567 return MAILSMTP_ERROR_STREAM;
568
569 default:
570 return MAILSMTP_ERROR_UNEXPECTED_CODE;
571 }
572}
573
574int auth_map_errors(int err)
575{
576 switch (err) {
577 case 235:
578 return MAILSMTP_NO_ERROR; /* AUTH successfull */
579 case 334:
580 return MAILSMTP_NO_ERROR; /* AUTH in progress */
581 case 432:
582 return MAILSMTP_ERROR_AUTH_TRANSITION_NEEDED;
583 case 454:
584 return MAILSMTP_ERROR_AUTH_TEMPORARY_FAILTURE;
585 case 504:
586 return MAILSMTP_ERROR_AUTH_NOT_SUPPORTED;
587 case 530:
588 return MAILSMTP_ERROR_AUTH_REQUIRED;
589 case 534:
590 return MAILSMTP_ERROR_AUTH_TOO_WEAK;
591 case 538:
592 return MAILSMTP_ERROR_AUTH_ENCRYPTION_REQUIRED;
593 default:
594 /* opportunistic approach ;) */
595 return MAILSMTP_NO_ERROR;
596 }
597}
598
599static int mailsmtp_auth_login(mailsmtp * session,
600 const char * user, const char * pass)
601{
602 int err;
603 char command[SMTP_STRING_SIZE];
604 char * user64, * pass64;
605
606 user64 = NULL;
607 pass64 = NULL;
608
609 user64 = encode_base64(user, strlen(user));
610 if (user64 == NULL) {
611 err = MAILSMTP_ERROR_MEMORY;
612 goto err_free;
613 }
614
615 pass64 = encode_base64(pass, strlen(pass));
616 if (pass64 == NULL) {
617 err = MAILSMTP_ERROR_MEMORY;
618 goto err_free;
619 }
620
621 snprintf(command, SMTP_STRING_SIZE, "%s\r\n", user64);
622 err = send_command(session, command);
623 if (err == -1) {
624 err = MAILSMTP_ERROR_STREAM;
625 goto err_free;
626 }
627 err = read_response(session);
628 err = auth_map_errors(err);
629 if (err != MAILSMTP_NO_ERROR)
630 goto err_free;
631
632 snprintf(command, SMTP_STRING_SIZE, "%s\r\n", pass64);
633 err = send_command(session, command);
634 if (err == -1) {
635 err = MAILSMTP_ERROR_STREAM;
636 goto err_free;
637 }
638 err = read_response(session);
639 err = auth_map_errors(err);
640
641 err_free:
642 free(user64);
643 free(pass64);
644
645 return err;
646}
647
648static int mailsmtp_auth_plain(mailsmtp * session,
649 const char * user, const char * pass)
650{
651 int err, len;
652 char command[SMTP_STRING_SIZE];
653 char * plain, * plain64;
654
655 len = strlen(user) + strlen(pass) + 3;
656 plain = (char *) malloc(len);
657 if (plain == NULL) {
658 err = MAILSMTP_ERROR_MEMORY;
659 goto err;
660 }
661
662 snprintf(plain, len, "%c%s%c%s", '\0', user, '\0', pass);
663 plain64 = encode_base64(plain, len - 1);
664
665 snprintf(command, SMTP_STRING_SIZE, "%s\r\n", plain64);
666 err = send_command(session, command);
667 if (err == -1) {
668 err = MAILSMTP_ERROR_STREAM;
669 goto err_free;
670 }
671
672 err = read_response(session);
673 err = auth_map_errors(err);
674
675err_free:
676 free(plain64);
677 free(plain);
678
679 err:
680 return err;
681}
682
683static char * convert_hex(unsigned char *in, int len)
684{
685 static char hex[] = "0123456789abcdef";
686 char * out;
687 int i;
688
689 out = (char *) malloc(len * 2 + 1);
690 if (out == NULL)
691 return NULL;
692
693 for (i = 0; i < len; i++) {
694 out[i * 2] = hex[in[i] >> 4];
695 out[i * 2 + 1] = hex[in[i] & 15];
696 }
697
698 out[i*2] = 0;
699
700 return out;
701}
702
703static char * hash_md5(const char * sec_key, const char * data, int len)
704{
705 char key[65], digest[24];
706 char * hash_hex;
707
708 int sec_len, i;
709
710 sec_len = strlen(sec_key);
711
712 if (sec_len < 64) {
713 memcpy(key, sec_key, sec_len);
714 for (i = sec_len; i < 64; i++) {
715 key[i] = 0;
716 }
717 } else {
718 memcpy(key, sec_key, 64);
719 }
720
721 hmac_md5(data, len, key, 64, digest);
722 hash_hex = convert_hex(digest, 16);
723
724 return hash_hex;
725}
726
727static int mailsmtp_auth_cram_md5(mailsmtp * session,
728 const char * user, const char * pass)
729{
730 int err;
731 char command[SMTP_STRING_SIZE];
732 char *response, *auth_hex, *auth;
733
734 response = decode_base64(session->response, strlen(session->response));
735 if (response == NULL) return MAILSMTP_ERROR_MEMORY;
736
737 auth_hex = hash_md5(pass, response, strlen(response));
738 if (auth_hex == NULL) {
739 err = MAILSMTP_ERROR_MEMORY;
740 goto err_free_response;
741 }
742
743 snprintf(command, SMTP_STRING_SIZE, "%s %s", user, auth_hex);
744
745 auth = encode_base64(command, strlen(command));
746 if (auth == NULL) {
747 err = MAILSMTP_ERROR_MEMORY;
748 goto err_free_auth_hex;
749 }
750
751 snprintf(command, SMTP_STRING_SIZE, "%s\r\n", auth);
752 err = send_command(session, command);
753 if (err == -1) {
754 err = MAILSMTP_ERROR_STREAM;
755 goto err_free;
756 }
757
758 err = read_response(session);
759 err = auth_map_errors(err);
760
761err_free:
762 free(auth);
763err_free_auth_hex:
764 free(auth_hex);
765err_free_response:
766 free(response);
767 return err;
768}
769
770int mailsmtp_auth_type(mailsmtp * session,
771 const char * user, const char * pass, int type)
772{
773 int err;
774 char command[SMTP_STRING_SIZE];
775
776 if (session->auth == MAILSMTP_AUTH_NOT_CHECKED)
777 return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND;
778
779 if ( !(session->auth & type) ) return MAILSMTP_ERROR_AUTH_NOT_SUPPORTED;
780
781 switch (type) {
782 case MAILSMTP_AUTH_LOGIN:
783 snprintf(command, SMTP_STRING_SIZE, "AUTH LOGIN\r\n");
784 break;
785 case MAILSMTP_AUTH_PLAIN:
786 snprintf(command, SMTP_STRING_SIZE, "AUTH PLAIN\r\n");
787 break;
788 case MAILSMTP_AUTH_CRAM_MD5:
789 snprintf(command, SMTP_STRING_SIZE, "AUTH CRAM-MD5\r\n");
790 break;
791 default:
792 return MAILSMTP_ERROR_NOT_IMPLEMENTED;
793 }
794
795 err = send_command(session, command);
796 if (err == -1) return MAILSMTP_ERROR_STREAM;
797
798 err = read_response(session);
799 err = auth_map_errors(err);
800 if (err != MAILSMTP_NO_ERROR) return err;
801
802 switch (type) {
803 case MAILSMTP_AUTH_LOGIN:
804 return mailsmtp_auth_login(session, user, pass);
805 case MAILSMTP_AUTH_PLAIN:
806 return mailsmtp_auth_plain(session, user, pass);
807 case MAILSMTP_AUTH_CRAM_MD5:
808 return mailsmtp_auth_cram_md5(session, user, pass);
809 default:
810 return MAILSMTP_ERROR_NOT_IMPLEMENTED;
811 }
812}
813
814
815int mailsmtp_auth(mailsmtp * session, const char * user, const char * pass)
816{
817 if (session->auth == MAILSMTP_AUTH_NOT_CHECKED)
818 return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND;
819
820 if (session->auth & MAILSMTP_AUTH_CRAM_MD5) {
821 return mailsmtp_auth_type(session, user, pass, MAILSMTP_AUTH_CRAM_MD5);
822 } else if (session->auth & MAILSMTP_AUTH_PLAIN) {
823 return mailsmtp_auth_type(session, user, pass, MAILSMTP_AUTH_PLAIN);
824 } else if (session->auth & MAILSMTP_AUTH_LOGIN) {
825 return mailsmtp_auth_type(session, user, pass, MAILSMTP_AUTH_LOGIN);
826 } else {
827 return MAILSMTP_ERROR_AUTH_NOT_SUPPORTED;
828 }
829}
830
831/* TODO: add mailesmtp_etrn, mailssmtp_expn */
832
833int mailesmtp_starttls(mailsmtp * session) {
834 int r;
835
836 if (!(session->esmtp & MAILSMTP_ESMTP_STARTTLS))
837 return MAILSMTP_ERROR_STARTTLS_NOT_SUPPORTED;
838
839 r = send_command(session, "STARTTLS\r\n");
840 if (r == -1)
841 return MAILSMTP_ERROR_STREAM;
842 r = read_response(session);
843
844 switch (r) {
845 case 220:
846 return MAILSMTP_NO_ERROR;
847
848 case 454:
849 return MAILSMTP_ERROR_STARTTLS_TEMPORARY_FAILURE;
850
851 default:
852 return MAILSMTP_ERROR_UNEXPECTED_CODE;
853 }
854}
855
856static int parse_response(mailsmtp * session,
857 char * response)
858{
859 char * message;
860 int code;
861 int cont = 0;
862
863 code = strtol(response, &message, 10);
864 if (* message == ' ')
865 mmap_string_append(session->response_buffer, message + 1);
866 else if (* message == '-') {
867 cont = SMTP_STATUS_CONTINUE;
868 mmap_string_append(session->response_buffer, message + 1);
869 }
870 else
871 mmap_string_append(session->response_buffer, message);
872
873 return code | cont;
874}
875
876static char * read_line(mailsmtp * session)
877{
878 return mailstream_read_line_remove_eol(session->stream,
879 session->line_buffer);
880}
881
882static int read_response(mailsmtp * session)
883{
884 char * line;
885 int code;
886
887 mmap_string_assign(session->response_buffer, "");
888
889 do {
890 line = read_line(session);
891
892 if (line != NULL) {
893 code = parse_response(session, line);
894 mmap_string_append_c(session->response_buffer, '\n');
895 }
896 else
897 code = 0;
898 }
899 while ((code & SMTP_STATUS_CONTINUE) != 0);
900
901 session->response = session->response_buffer->str;
902
903 return code;
904}
905
906
907
908
909
910static int send_command(mailsmtp * f, char * command)
911{
912 ssize_t r;
913
914 r = mailstream_write(f->stream, command, strlen(command));
915 if (r == -1)
916 return -1;
917
918 r = mailstream_flush(f->stream);
919 if (r == -1)
920 return -1;
921
922 return 0;
923}
924
925static int send_data(mailsmtp * session, const char * message, size_t size)
926{
927 if (mailstream_send_data(session->stream, message, size,
928 session->progr_rate, session->progr_fun) == -1)
929 return -1;
930
931 if (mailstream_flush(session->stream) == -1)
932 return -1;
933
934 return 0;
935}
936
937
938const char * mailsmtp_strerror(int errnum)
939{
940 switch (errnum) {
941 case MAILSMTP_NO_ERROR:
942 return "No error";
943 case MAILSMTP_ERROR_UNEXPECTED_CODE:
944 return "Unexpected error code";
945 case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
946 return "Service not available";
947 case MAILSMTP_ERROR_STREAM:
948 return "Stream error";
949 case MAILSMTP_ERROR_HOSTNAME:
950 return "gethostname() failed";
951 case MAILSMTP_ERROR_NOT_IMPLEMENTED:
952 return "Not implemented";
953 case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
954 return "Error, action not taken";
955 case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
956 return "Data exceeds storage allocation";
957 case MAILSMTP_ERROR_IN_PROCESSING:
958 return "Error in processing";
959 case MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE:
960 return "Insufficient system storage";
961 case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
962 return "Mailbox unavailable";
963 case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
964 return "Mailbox name not allowed";
965 case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND:
966 return "Bad command sequence";
967 case MAILSMTP_ERROR_USER_NOT_LOCAL:
968 return "User not local";
969 case MAILSMTP_ERROR_TRANSACTION_FAILED:
970 return "Transaction failed";
971 case MAILSMTP_ERROR_MEMORY:
972 return "Memory error";
973 case MAILSMTP_ERROR_CONNECTION_REFUSED:
974 return "Connection refused";
975 case MAILSMTP_ERROR_STARTTLS_TEMPORARY_FAILURE:
976 return "TLS not available on server for temporary reason";
977 case MAILSMTP_ERROR_STARTTLS_NOT_SUPPORTED:
978 return "TLS not supported by server";
979 default:
980 return "Unknown error code";
981 }
982}
diff --git a/kmicromail/libetpan/smtp/mailsmtp.h b/kmicromail/libetpan/smtp/mailsmtp.h
new file mode 100644
index 0000000..548a5b7
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp.h
@@ -0,0 +1,94 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSMTP_H
37
38#define MAILSMTP_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <libetpan/mailsmtp_types.h>
45#include <libetpan/mailsmtp_helper.h>
46#include <libetpan/mailsmtp_socket.h>
47#include <libetpan/mailsmtp_ssl.h>
48
49
50mailsmtp * mailsmtp_new(size_t progr_rate,
51 progress_function * progr_fun);
52void mailsmtp_free(mailsmtp * session);
53
54int mailsmtp_connect(mailsmtp * session, mailstream * s);
55int mailsmtp_quit(mailsmtp * session);
56
57/**
58 * Tries AUTH with detected method - "better" method first:
59 * CRAM-MD5 -> PLAIN -> LOGIN
60 */
61int mailsmtp_auth(mailsmtp * session, const char * user, const char * pass);
62
63/**
64 * tries to autenticate with the server using given auth-type
65 * returns MAILSMTP_NO_ERROR on success
66 */
67int mailsmtp_auth_type(mailsmtp * session,
68 const char * user, const char * pass, int type);
69
70int mailsmtp_helo(mailsmtp * session);
71int mailsmtp_mail(mailsmtp * session, const char * from);
72int mailsmtp_rcpt(mailsmtp * session, const char * to);
73int mailsmtp_data(mailsmtp * session);
74int mailsmtp_data_message(mailsmtp * session,
75 const char * message,
76 size_t size);
77int mailesmtp_ehlo(mailsmtp * session);
78int mailesmtp_mail(mailsmtp * session,
79 const char * from,
80 int return_full,
81 const char * envid);
82int mailesmtp_rcpt(mailsmtp * session,
83 const char * to,
84 int notify,
85 const char * orcpt);
86int mailesmtp_starttls(mailsmtp * session);
87
88const char * mailsmtp_strerror(int errnum);
89
90#ifdef __cplusplus
91}
92#endif
93
94#endif
diff --git a/kmicromail/libetpan/smtp/mailsmtp_helper.c b/kmicromail/libetpan/smtp/mailsmtp_helper.c
new file mode 100644
index 0000000..32d6564
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp_helper.c
@@ -0,0 +1,232 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailsmtp.h"
37#include <string.h>
38#include <stdlib.h>
39#include "mail.h"
40
41int mailsmtp_init(mailsmtp * session)
42{
43 int r;
44 session->esmtp = 0;
45 r = mailesmtp_ehlo(session);
46
47 if (r == MAILSMTP_NO_ERROR) {
48 // session->esmtp = TRUE;
49 return MAILSMTP_NO_ERROR;
50 }
51
52 r = mailsmtp_helo(session);
53 /* if (r == MAILSMTP_NO_ERROR) { */
54/* session->esmtp = FALSE; */
55/* return MAILSMTP_NO_ERROR; */
56/* } */
57
58 return r;
59}
60
61
62
63int mailesmtp_send(mailsmtp * session,
64 const char * from,
65 int return_full,
66 const char * envid,
67 clist * addresses,
68 const char * message, size_t size)
69{
70 int r;
71 clistiter * l;
72
73 if (!session->esmtp)
74 return mailsmtp_send(session, from, addresses, message, size);
75
76 r = mailesmtp_mail(session, from, return_full, envid);
77 if (r != MAILSMTP_NO_ERROR)
78 return r;
79
80 for(l = clist_begin(addresses) ; l != NULL; l = clist_next(l)) {
81 struct esmtp_address * addr;
82
83 addr = clist_content(l);
84
85 r = mailesmtp_rcpt(session, addr->address, addr->notify, addr->orcpt);
86 if (r != MAILSMTP_NO_ERROR)
87 return r;
88 }
89
90 r = mailsmtp_data(session);
91 if (r != MAILSMTP_NO_ERROR)
92 return r;
93
94 r = mailsmtp_data_message(session, message, size);
95 if (r != MAILSMTP_NO_ERROR)
96 return r;
97
98 return MAILSMTP_NO_ERROR;
99}
100
101int mailsmtp_send(mailsmtp * session,
102 const char * from,
103 clist * addresses,
104 const char * message, size_t size)
105{
106 int r;
107 clistiter * l;
108
109 r = mailsmtp_mail(session, from);
110 if (r != MAILSMTP_NO_ERROR)
111 return r;
112
113 for(l = clist_begin(addresses) ; l != NULL; l = clist_next(l)) {
114 struct esmtp_address * addr;
115
116 addr = clist_content(l);
117
118 r = mailsmtp_rcpt(session, addr->address);
119 if (r != MAILSMTP_NO_ERROR)
120 return r;
121 }
122
123 r = mailsmtp_data(session);
124 if (r != MAILSMTP_NO_ERROR)
125 return r;
126
127 r = mailsmtp_data_message(session, message, size);
128 if (r != MAILSMTP_NO_ERROR)
129 return r;
130
131 return MAILSMTP_NO_ERROR;
132}
133
134
135
136
137
138
139
140
141
142
143
144
145
146/* esmtp addresses and smtp addresses */
147
148static struct esmtp_address * esmtp_address_new(char * addr,
149 int notify, char * orcpt)
150{
151 struct esmtp_address * esmtpa;
152
153 esmtpa = malloc(sizeof(* esmtpa));
154 if (esmtpa == NULL)
155 return NULL;
156
157 esmtpa->address = strdup(addr);
158 if (esmtpa->address == NULL) {
159 free(esmtpa);
160 return NULL;
161 }
162
163 if (orcpt != NULL) {
164 esmtpa->orcpt = strdup(orcpt);
165 if (esmtpa->orcpt == NULL) {
166 free(esmtpa->address);
167 free(esmtpa);
168 return NULL;
169 }
170 }
171 else
172 esmtpa->orcpt = NULL;
173
174 esmtpa->notify = notify;
175
176 return esmtpa;
177}
178
179static void esmtp_address_free(struct esmtp_address * addr)
180{
181 if (addr->orcpt)
182 free(addr->orcpt);
183 if (addr->address)
184 free(addr->address);
185
186 free(addr);
187}
188
189clist * esmtp_address_list_new()
190{
191 return clist_new();
192}
193
194void esmtp_address_list_free(clist * l)
195{
196 clist_foreach(l, (clist_func) esmtp_address_free, NULL);
197 clist_free(l);
198}
199
200int esmtp_address_list_add(clist * list, char * address,
201 int notify, char * orcpt)
202{
203 struct esmtp_address * esmtpa;
204 int r;
205
206 esmtpa = esmtp_address_new(address, notify, orcpt);
207 if (esmtpa == NULL)
208 return -1;
209
210 r = clist_append(list, esmtpa);
211 if (r < 0) {
212 esmtp_address_free(esmtpa);
213 return -1;
214 }
215
216 return 0;
217}
218
219clist * smtp_address_list_new()
220{
221 return esmtp_address_list_new();
222}
223
224int smtp_address_list_add(clist * list, char * address)
225{
226 return esmtp_address_list_add(list, address, 0, NULL);
227}
228
229void smtp_address_list_free(clist * l)
230{
231 esmtp_address_list_free(l);
232}
diff --git a/kmicromail/libetpan/smtp/mailsmtp_helper.h b/kmicromail/libetpan/smtp/mailsmtp_helper.h
new file mode 100644
index 0000000..6bbe3c9
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp_helper.h
@@ -0,0 +1,74 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSMTP_HELPER_H
37
38#define MAILSMTP_HELPER_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mailsmtp_types.h"
45#include "clist.h"
46
47int mailsmtp_init(mailsmtp * session);
48
49int mailesmtp_send(mailsmtp * session,
50 const char * from,
51 int return_full,
52 const char * envid,
53 clist * addresses,
54 const char * message, size_t size);
55
56int mailsmtp_send(mailsmtp * session,
57 const char * from,
58 clist * addresses,
59 const char * message, size_t size);
60
61clist * esmtp_address_list_new();
62int esmtp_address_list_add(clist * list, char * address,
63 int notify, char * orcpt);
64void esmtp_address_list_free(clist * l);
65
66clist * smtp_address_list_new();
67int smtp_address_list_add(clist * list, char * address);
68void smtp_address_list_free(clist * l);
69
70#ifdef __cplusplus
71}
72#endif
73
74#endif
diff --git a/kmicromail/libetpan/smtp/mailsmtp_socket.c b/kmicromail/libetpan/smtp/mailsmtp_socket.c
new file mode 100644
index 0000000..b847bf2
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp_socket.c
@@ -0,0 +1,99 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailsmtp_socket.h"
37
38#include "mailsmtp.h"
39
40#include "connect.h"
41#include <netinet/in.h>
42#include <unistd.h>
43
44#define DEFAULT_SMTP_PORT 25
45#define SERVICE_NAME_SMTP "smtp"
46#define SERVICE_TYPE_TCP "tcp"
47
48int mailsmtp_socket_connect(mailsmtp * session,
49 const char * server, uint16_t port)
50{
51 int s;
52 mailstream * stream;
53
54 if (port == 0) {
55 port = mail_get_service_port(SERVICE_NAME_SMTP, SERVICE_TYPE_TCP);
56 if (port == 0)
57 port = DEFAULT_SMTP_PORT;
58 port = ntohs(port);
59 }
60
61 /* Connection */
62
63 s = mail_tcp_connect(server, port);
64 if (s == -1)
65 return MAILSMTP_ERROR_CONNECTION_REFUSED;
66
67 stream = mailstream_socket_open(s);
68 if (stream == NULL) {
69 close(s);
70 return MAILSMTP_ERROR_MEMORY;
71 }
72
73 return mailsmtp_connect(session, stream);
74}
75
76int mailsmtp_socket_starttls(mailsmtp * session) {
77 int r;
78 int fd;
79 mailstream_low * low;
80 mailstream_low * new_low;
81
82 r = mailesmtp_starttls(session);
83 if (r != MAILSMTP_NO_ERROR)
84 return r;
85
86 low = mailstream_get_low(session->stream);
87 fd = mailstream_low_get_fd(low);
88 if (fd == -1)
89 return MAILSMTP_ERROR_STREAM;
90
91 new_low = mailstream_low_ssl_open(fd);
92 if (new_low == NULL)
93 return MAILSMTP_ERROR_STREAM;
94
95 mailstream_low_free(low);
96 mailstream_set_low(session->stream, new_low);
97
98 return MAILSMTP_NO_ERROR;
99}
diff --git a/kmicromail/libetpan/smtp/mailsmtp_socket.h b/kmicromail/libetpan/smtp/mailsmtp_socket.h
new file mode 100644
index 0000000..6691d9e
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp_socket.h
@@ -0,0 +1,56 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSMTP_SOCKET_H
37
38#define MAILSMTP_SOCKET_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45
46#include <libetpan/mailsmtp_types.h>
47
48int mailsmtp_socket_connect(mailsmtp * session,
49 const char * server, uint16_t port);
50int mailsmtp_socket_starttls(mailsmtp * session);
51
52#ifdef __cplusplus
53}
54#endif
55
56#endif
diff --git a/kmicromail/libetpan/smtp/mailsmtp_ssl.c b/kmicromail/libetpan/smtp/mailsmtp_ssl.c
new file mode 100644
index 0000000..eea31de
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp_ssl.c
@@ -0,0 +1,74 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailsmtp_socket.h"
37
38#include "mailsmtp.h"
39
40#include "connect.h"
41#include <netinet/in.h>
42#include <unistd.h>
43
44#define DEFAULT_SMTPS_PORT 465
45#define SERVICE_NAME_SMTPS "smtps"
46#define SERVICE_TYPE_TCP "tcp"
47
48int mailsmtp_ssl_connect(mailsmtp * session,
49 const char * server, uint16_t port)
50{
51 int s;
52 mailstream * stream;
53
54 if (port == 0) {
55 port = mail_get_service_port(SERVICE_NAME_SMTPS, SERVICE_TYPE_TCP);
56 if (port == 0)
57 port = DEFAULT_SMTPS_PORT;
58 port = ntohs(port);
59 }
60
61 /* Connection */
62
63 s = mail_tcp_connect(server, port);
64 if (s == -1)
65 return MAILSMTP_ERROR_CONNECTION_REFUSED;
66
67 stream = mailstream_ssl_open(s);
68 if (stream == NULL) {
69 close(s);
70 return MAILSMTP_ERROR_CONNECTION_REFUSED;
71 }
72
73 return mailsmtp_connect(session, stream);
74}
diff --git a/kmicromail/libetpan/smtp/mailsmtp_ssl.h b/kmicromail/libetpan/smtp/mailsmtp_ssl.h
new file mode 100644
index 0000000..9de9732
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp_ssl.h
@@ -0,0 +1,55 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSMTP_SSL_H
37
38#define MAILSMTP_SSL_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <inttypes.h>
45
46#include <libetpan/mailsmtp_types.h>
47
48int mailsmtp_ssl_connect(mailsmtp * session,
49 const char * server, uint16_t port);
50
51#ifdef __cplusplus
52}
53#endif
54
55#endif
diff --git a/kmicromail/libetpan/smtp/mailsmtp_types.h b/kmicromail/libetpan/smtp/mailsmtp_types.h
new file mode 100644
index 0000000..b63d5ea
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp_types.h
@@ -0,0 +1,126 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSMTP_TYPES_H
37
38#define MAILSMTP_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include "mailstream.h"
45#include "mmapstring.h"
46
47enum {
48 MAILSMTP_NO_ERROR = 0,
49 MAILSMTP_ERROR_UNEXPECTED_CODE,
50 MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE,
51 MAILSMTP_ERROR_STREAM,
52 MAILSMTP_ERROR_HOSTNAME,
53 MAILSMTP_ERROR_NOT_IMPLEMENTED,
54 MAILSMTP_ERROR_ACTION_NOT_TAKEN,
55 MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION,
56 MAILSMTP_ERROR_IN_PROCESSING,
57 MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE,
58 MAILSMTP_ERROR_MAILBOX_UNAVAILABLE,
59 MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED,
60 MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND,
61 MAILSMTP_ERROR_USER_NOT_LOCAL,
62 MAILSMTP_ERROR_TRANSACTION_FAILED,
63 MAILSMTP_ERROR_MEMORY,
64 MAILSMTP_ERROR_AUTH_NOT_SUPPORTED,
65 MAILSMTP_ERROR_AUTH_LOGIN,
66 MAILSMTP_ERROR_AUTH_REQUIRED,
67 MAILSMTP_ERROR_AUTH_TOO_WEAK,
68 MAILSMTP_ERROR_AUTH_TRANSITION_NEEDED,
69 MAILSMTP_ERROR_AUTH_TEMPORARY_FAILTURE,
70 MAILSMTP_ERROR_AUTH_ENCRYPTION_REQUIRED,
71 MAILSMTP_ERROR_STARTTLS_TEMPORARY_FAILURE,
72 MAILSMTP_ERROR_STARTTLS_NOT_SUPPORTED,
73 MAILSMTP_ERROR_CONNECTION_REFUSED
74};
75
76enum {
77 MAILSMTP_AUTH_NOT_CHECKED = 0,
78 MAILSMTP_AUTH_CHECKED = 1,
79 MAILSMTP_AUTH_CRAM_MD5 = 2,
80 MAILSMTP_AUTH_PLAIN = 4,
81 MAILSMTP_AUTH_LOGIN = 8
82};
83
84enum {
85 MAILSMTP_ESMTP = 1,
86 MAILSMTP_ESMTP_EXPN = 2,
87 MAILSMTP_ESMTP_8BITMIME = 4,
88 MAILSMTP_ESMTP_SIZE = 8,
89 MAILSMTP_ESMTP_ETRN = 16,
90 MAILSMTP_ESMTP_STARTTLS = 32,
91 MAILSMTP_ESMTP_DSN = 64,
92};
93
94struct mailsmtp {
95 mailstream * stream;
96
97 size_t progr_rate;
98 progress_function * progr_fun;
99
100 char * response;
101
102 MMAPString * line_buffer;
103 MMAPString * response_buffer;
104
105 int esmtp; // contains flags MAILSMTP_ESMTP_*
106 int auth; // contains flags MAILSMTP_AUTH_*
107};
108
109typedef struct mailsmtp mailsmtp;
110
111#define MAILSMTP_DSN_NOTIFY_SUCCESS 1
112#define MAILSMTP_DSN_NOTIFY_FAILURE 2
113#define MAILSMTP_DSN_NOTIFY_DELAY 4
114#define MAILSMTP_DSN_NOTIFY_NEVER 8
115
116struct esmtp_address {
117 char * address;
118 int notify;
119 char * orcpt;
120};
121
122#ifdef __cplusplus
123}
124#endif
125
126#endif
diff --git a/kmicromail/libetpan/tests/README b/kmicromail/libetpan/tests/README
new file mode 100644
index 0000000..66d8b2f
--- a/dev/null
+++ b/kmicromail/libetpan/tests/README
@@ -0,0 +1,58 @@
1compose-msg
2-----------
3
4creates a RFC 2822 message with MIME parts
5
6syntax: compose-msg "text" filename
7
8
9
10all the following programs will take as argument :
11
12 --driver=(pop3|imap|nntp|mbox|mh) -d pop3 (pop3|imap|nntp|mbox|mh)
13
14 default driver is mbox
15
16 --server={server-name} -s {server-name}
17 --port={port-number} -p {port-number}
18 --tls -t
19 --starttls -x
20 --user={login} -u {login}
21 --password={password} -v {password}
22 --path={mailbox} -l {mailbox}
23 --apop -a
24 --cache={directory} -c {directory}
25
26the default driver is mbox with the path /var/mail/$USER
27
28frm-simple, frm, frm-tree
29-------------------------
30
31frm-simple will list all the mails of a mailbox without any MIME decoding.
32
33frm will list all the mails of a mailbox and will decode the fields.
34
35frm-tree will do the same thing as frm and will also show the threads
36 of the folder.
37
38
39fetch-attachment
40----------------
41
42 fetch-attachment gets all the named attachment of the given message
43of the chosen mailbox and writes them on the current directory.
44
45 The program should be given message numbers (as given by frm) as
46additionnal arguments.
47
48
49readmsg-simple, readmsg
50-----------------------
51
52 readmsg-simple will display the content of the given messages.
53All the content (headers and body) will be displayed.
54
55 readmsg will display only the text parts of the given messages.
56
57 The program should be given message numbers (as given by frm) as
58additionnal arguments.
diff --git a/kmicromail/libetpan/tests/compose-msg.c b/kmicromail/libetpan/tests/compose-msg.c
new file mode 100644
index 0000000..f68660b
--- a/dev/null
+++ b/kmicromail/libetpan/tests/compose-msg.c
@@ -0,0 +1,317 @@
1#include <libetpan/libetpan.h>
2#include <string.h>
3#include <stdlib.h>
4
5#define DEST_CHARSET "iso-8859-1"
6
7/* build a mime parameter */
8
9static struct mailmime_parameter *
10mailmime_param_new_with_data(char * name, char * value)
11{
12 char * param_name;
13 char * param_value;
14 struct mailmime_parameter * param;
15
16 param_name = strdup(name);
17 if (param_name == NULL)
18 goto err;
19
20 param_value = strdup(value);
21 if (param_value == NULL)
22 goto free_name;
23
24 param = mailmime_parameter_new(param_name, param_value);
25 if (param == NULL)
26 goto free_value;
27
28 return param;
29
30 free_value:
31 free(param_value);
32 free_name:
33 free(param_name);
34 err:
35 return NULL;
36}
37
38
39/* build sample fields */
40
41static struct mailimf_fields * build_fields(void)
42{
43 struct mailimf_mailbox_list * from;
44 struct mailimf_address_list * to;
45 char * subject;
46 int r;
47 struct mailimf_fields * new_fields;
48
49 /* subject field */
50
51 subject = strdup("this is a sample");
52 if (subject == NULL) {
53 goto err;
54 }
55
56 /* from field */
57
58 from = mailimf_mailbox_list_new_empty();
59 if (from == NULL) {
60 goto free_subject;
61 }
62
63 r = mailimf_mailbox_list_add_parse(from,
64 "DINH Viet Hoa <hoa@sourceforge.net>");
65 if (r != MAILIMF_NO_ERROR) {
66 goto free_from;
67 }
68
69 /* to field */
70
71 to = mailimf_address_list_new_empty();
72 if (to == NULL) {
73 goto free_from;
74 }
75
76 r = mailimf_address_list_add_parse(to,
77 "Paul <claws@thewildbeast.co.uk>");
78 if (r != MAILIMF_NO_ERROR) {
79 goto free_to;
80 }
81
82 new_fields = mailimf_fields_new_with_data(from /* from */,
83 NULL /* sender */, NULL /* reply-to */,
84 to, NULL /* cc */, NULL /* bcc */, NULL /* in-reply-to */,
85 NULL /* references */,
86 subject);
87 if (new_fields == NULL)
88 goto free_to;
89
90 return new_fields;
91
92 free_to:
93 mailimf_address_list_free(to);
94 free_from:
95 mailimf_mailbox_list_free(from);
96 free_subject:
97 free(subject);
98 err:
99 return NULL;
100}
101
102
103
104/* text is a string, build a mime part containing this string */
105
106static struct mailmime * build_body_text(char * text)
107{
108 struct mailmime_fields * mime_fields;
109 struct mailmime * mime_sub;
110 struct mailmime_content * content;
111 struct mailmime_parameter * param;
112 int r;
113
114 /* text/plain part */
115
116 mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT);
117 if (mime_fields == NULL) {
118 goto err;
119 }
120
121 content = mailmime_content_new_with_str("text/plain");
122 if (content == NULL) {
123 goto free_fields;
124 }
125
126 param = mailmime_param_new_with_data("charset", DEST_CHARSET);
127 if (param == NULL) {
128 goto free_content;
129 }
130
131 r = clist_append(content->ct_parameters, param);
132 if (r < 0) {
133 mailmime_parameter_free(param);
134 goto free_content;
135 }
136
137 mime_sub = mailmime_new_empty(content, mime_fields);
138 if (mime_sub == NULL) {
139 goto free_content;
140 }
141
142 r = mailmime_set_body_text(mime_sub, text, strlen(text));
143 if (r != MAILIMF_NO_ERROR) {
144 goto free_mime;
145 }
146
147 return mime_sub;
148
149 free_mime:
150 mailmime_free(mime_sub);
151 goto err;
152 free_content:
153 mailmime_content_free(content);
154 free_fields:
155 mailmime_fields_free(mime_fields);
156 err:
157 return NULL;
158}
159
160
161/* build a mime part containing the given file */
162
163static struct mailmime * build_body_file(char * filename)
164{
165 struct mailmime_fields * mime_fields;
166 struct mailmime * mime_sub;
167 struct mailmime_content * content;
168 struct mailmime_parameter * param;
169 char * dup_filename;
170 int r;
171
172 /* text/plain part */
173
174 dup_filename = strdup(filename);
175 if (dup_filename == NULL)
176 goto err;
177
178 mime_fields =
179 mailmime_fields_new_filename(MAILMIME_DISPOSITION_TYPE_ATTACHMENT,
180 dup_filename, MAILMIME_MECHANISM_BASE64);
181 if (mime_fields == NULL)
182 goto free_dup_filename;
183
184 content = mailmime_content_new_with_str("text/plain");
185 if (content == NULL) {
186 goto free_fields;
187 }
188
189 param = mailmime_param_new_with_data("charset", DEST_CHARSET);
190 if (param == NULL) {
191 goto free_content;
192 }
193
194 r = clist_append(content->ct_parameters, param);
195 if (r < 0) {
196 mailmime_parameter_free(param);
197 goto free_content;
198 }
199
200 mime_sub = mailmime_new_empty(content, mime_fields);
201 if (mime_sub == NULL) {
202 goto free_content;
203 }
204
205 dup_filename = strdup(filename);
206 if (dup_filename == NULL)
207 goto free_mime;
208
209 r = mailmime_set_body_file(mime_sub, dup_filename);
210 if (r != MAILIMF_NO_ERROR) {
211 goto free_mime;
212 }
213
214 return mime_sub;
215
216 free_mime:
217 mailmime_free(mime_sub);
218 goto err;
219 free_content:
220 mailmime_content_free(content);
221 free_fields:
222 mailmime_fields_free(mime_fields);
223 goto err;
224 free_dup_filename:
225 free(dup_filename);
226 err:
227 return NULL;
228}
229
230
231/* build an empty message */
232
233static struct mailmime * build_message(struct mailimf_fields * fields)
234{
235 struct mailmime * mime;
236
237 /* message */
238
239 mime = mailmime_new_message_data(NULL);
240 if (mime == NULL) {
241 goto err;
242 }
243
244 mailmime_set_imf_fields(mime, fields);
245
246 return mime;
247
248 err:
249 return NULL;
250}
251
252
253int main(int argc, char ** argv)
254{
255 struct mailimf_fields * fields;
256 char * text;
257 char * filename;
258 struct mailmime * message;
259 struct mailmime * text_part;
260 struct mailmime * file_part;
261 int r;
262 int col;
263
264 if (argc < 3) {
265 printf("syntax: compose-msg \"text\" filename\n");
266 return 1;
267 }
268
269 fields = build_fields();
270 if (fields == NULL)
271 goto err;
272
273 message = build_message(fields);
274 if (message == NULL)
275 goto free_fields;
276
277 text = argv[1];
278 text_part = build_body_text(text);
279 if (text_part == NULL)
280 goto free_message;
281
282 filename = argv[2];
283 file_part = build_body_file(filename);
284 if (file_part == NULL)
285 goto free_text;
286
287 r = mailmime_smart_add_part(message, text_part);
288 if (r != MAILIMF_NO_ERROR)
289 goto free_file;
290
291 r = mailmime_smart_add_part(message, file_part);
292 if (r != MAILIMF_NO_ERROR)
293 goto free_file_alone;
294
295 col = 0;
296 mailmime_write(stdout, &col, message);
297
298 mailmime_free(message);
299
300 return 0;
301
302 free_file_alone:
303 mailmime_free(file_part);
304 goto free_text;
305 free_file:
306 mailmime_free(file_part);
307 free_text:
308 mailmime_free(text_part);
309 free_message:
310 mailmime_free(message);
311 goto err;
312 free_fields:
313 mailimf_fields_free(fields);
314 err:
315 printf("error memory\n");
316 return 1;
317}
diff --git a/kmicromail/libetpan/tests/fetch-attachment.c b/kmicromail/libetpan/tests/fetch-attachment.c
new file mode 100644
index 0000000..a79ef8b
--- a/dev/null
+++ b/kmicromail/libetpan/tests/fetch-attachment.c
@@ -0,0 +1,274 @@
1#include <unistd.h>
2#include <string.h>
3#include <stdlib.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6
7#include <libetpan/libetpan.h>
8
9#include "option-parser.h"
10#include "readmsg-common.h"
11
12/* write content to the given filename */
13
14static int etpan_write_data(char * filename, char * data, size_t len)
15{
16 size_t write_len;
17 FILE * f;
18 int res;
19 mode_t old_umask;
20
21 old_umask = umask(0077);
22 f = fopen(filename, "w");
23 umask(old_umask);
24 if (f == NULL) {
25 res = ERROR_FILE;
26 goto err;
27 }
28
29 write_len = fwrite(data, 1, len, f);
30 if (write_len < len) {
31 res = ERROR_FILE;
32 goto close;
33 }
34
35 fclose(f);
36
37 return NO_ERROR;
38
39 close:
40 fclose(f);
41 err:
42 return res;
43}
44
45
46/* save attachment */
47
48static int save_mime_content(mailmessage * msg_info,
49 struct mailmime * mime_part)
50{
51 char * body;
52 size_t body_len;
53 int r;
54 char * filename;
55 struct mailmime_single_fields fields;
56 int res;
57
58 memset(&fields, 0, sizeof(struct mailmime_single_fields));
59 if (mime_part->mm_mime_fields != NULL)
60 mailmime_single_fields_init(&fields, mime_part->mm_mime_fields,
61 mime_part->mm_content_type);
62
63 filename = fields.fld_disposition_filename;
64
65 if (filename == NULL)
66 filename = fields.fld_content_name;
67
68 if (filename == NULL)
69 return ERROR_INVAL;
70
71 r = etpan_fetch_message(msg_info, mime_part, &fields, &body, &body_len);
72 if (r != NO_ERROR) {
73 res = r;
74 goto err;
75 }
76
77 printf("writing %s, %i bytes\n", filename, body_len);
78
79 r = etpan_write_data(filename, body, body_len);
80 if (r != NO_ERROR) {
81 res = r;
82 goto free;
83 }
84
85 mailmime_decoded_part_free(body);
86
87 return NO_ERROR;
88
89 free:
90 mailmime_decoded_part_free(body);
91 err:
92 return res;
93}
94
95
96
97/* fetch attachments */
98
99static int etpan_fetch_mime(FILE * f, mailmessage * msg_info,
100 struct mailmime * mime)
101{
102 int r;
103 clistiter * cur;
104 struct mailmime_single_fields fields;
105 int res;
106
107 memset(&fields, 0, sizeof(struct mailmime_single_fields));
108 if (mime->mm_mime_fields != NULL)
109 mailmime_single_fields_init(&fields, mime->mm_mime_fields,
110 mime->mm_content_type);
111
112 switch(mime->mm_type) {
113 case MAILMIME_SINGLE:
114 save_mime_content(msg_info, mime);
115
116 break;
117
118 case MAILMIME_MULTIPLE:
119
120 for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ;
121 cur != NULL ; cur = clist_next(cur)) {
122
123 r = etpan_fetch_mime(f, msg_info, clist_content(cur));
124 if (r != NO_ERROR) {
125 res = r;
126 goto err;
127 }
128 }
129
130 break;
131
132 case MAILMIME_MESSAGE:
133
134 if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
135 r = etpan_fetch_mime(f, msg_info, mime->mm_data.mm_message.mm_msg_mime);
136 if (r != NO_ERROR) {
137 res = r;
138 goto err;
139 }
140 }
141
142 break;
143 }
144
145 return NO_ERROR;
146
147 err:
148 return res;
149}
150
151
152int main(int argc, char ** argv)
153{
154 int r;
155 int driver;
156 char * server;
157 int port;
158 int connection_type;
159 char * user;
160 char * password;
161 int auth_type;
162 char * path;
163 char * cache_directory;
164 char * flags_directory;
165 struct mailstorage * storage;
166 int cached;
167 struct mailfolder * folder;
168
169 /* get options */
170
171 r = parse_options(argc, argv,
172 &driver, &server, &port, &connection_type,
173 &user, &password, &auth_type,
174 &path, &cache_directory, &flags_directory);
175
176 cached = (cache_directory != NULL);
177
178 /* build the storage structure */
179
180 storage = mailstorage_new(NULL);
181 if (storage == NULL) {
182 printf("error initializing storage\n");
183 goto free_opt;
184 }
185
186 r = init_storage(storage, driver, server, port, connection_type,
187 user, password, auth_type, path, cache_directory, flags_directory);
188 if (r != MAIL_NO_ERROR) {
189 printf("error initializing storage\n");
190 goto free_opt;
191 }
192
193 /* get the folder structure */
194
195 folder = mailfolder_new(storage, path, NULL);
196 if (folder == NULL) {
197 printf("error initializing folder\n");
198 goto free_storage;
199 }
200
201 r = mailfolder_connect(folder);
202 if (r != MAIL_NO_ERROR) {
203 printf("error initializing folder\n");
204 goto free_folder;
205 }
206
207 while (optind < argc) {
208 mailmessage * msg;
209 uint32_t msg_num;
210 struct mailmime * mime;
211
212 msg_num = strtoul(argv[optind], NULL, 10);
213
214 r = mailsession_get_message(folder->fld_session, msg_num, &msg);
215 if (r != MAIL_NO_ERROR) {
216 printf("** message %i not found ** - %s\n", msg_num,
217 maildriver_strerror(r));
218 optind ++;
219 continue;
220 }
221
222 r = mailmessage_get_bodystructure(msg, &mime);
223 if (r != MAIL_NO_ERROR) {
224 printf("** message %i not found - %s **\n", msg_num,
225 maildriver_strerror(r));
226 mailmessage_free(msg);
227 optind ++;
228 continue;
229 }
230
231 r = etpan_fetch_mime(stdout, msg, mime);
232
233 mailmessage_free(msg);
234
235 optind ++;
236 }
237
238 mailfolder_free(folder);
239 mailstorage_free(storage);
240
241 if (server != NULL)
242 free(server);
243 if (user != NULL)
244 free(user);
245 if (password != NULL)
246 free(password);
247 if (path != NULL)
248 free(path);
249 if (cache_directory != NULL)
250 free(cache_directory);
251 if (flags_directory != NULL)
252 free(flags_directory);
253
254 return 0;
255
256 free_folder:
257 mailfolder_free(folder);
258 free_storage:
259 mailstorage_free(storage);
260 free_opt:
261 if (server != NULL)
262 free(server);
263 if (user != NULL)
264 free(user);
265 if (password != NULL)
266 free(password);
267 if (path != NULL)
268 free(path);
269 if (cache_directory != NULL)
270 free(cache_directory);
271 if (flags_directory != NULL)
272 free(flags_directory);
273 return -1;
274}
diff --git a/kmicromail/libetpan/tests/frm-common.c b/kmicromail/libetpan/tests/frm-common.c
new file mode 100644
index 0000000..eeeadf0
--- a/dev/null
+++ b/kmicromail/libetpan/tests/frm-common.c
@@ -0,0 +1,158 @@
1#include "frm-common.h"
2
3#include <string.h>
4#include <stdlib.h>
5
6#define DEST_CHARSET "iso-8859-1"
7
8/* get part of the from field to display */
9
10void get_from_value(struct mailimf_single_fields * fields,
11 char ** from, int * is_addr)
12{
13 struct mailimf_mailbox * mb;
14
15 if (fields->fld_from == NULL) {
16 * from = NULL;
17 * is_addr = 0;
18 return;
19 }
20
21 if (clist_isempty(fields->fld_from->frm_mb_list->mb_list)) {
22 * from = NULL;
23 * is_addr = 0;
24 return;
25 }
26
27 mb = clist_begin(fields->fld_from->frm_mb_list->mb_list)->data;
28
29 if (mb->mb_display_name != NULL) {
30 * from = mb->mb_display_name;
31 * is_addr = 0;
32 }
33 else {
34 * from = mb->mb_addr_spec;
35 * is_addr = 1;
36 }
37}
38
39/* remove all CR and LF of a string and replace them with SP */
40
41void strip_crlf(char * str)
42{
43 char * p;
44
45 for(p = str ; * p != '\0' ; p ++) {
46 if ((* p == '\n') || (* p == '\r'))
47 * p = ' ';
48 }
49}
50
51#define MAX_OUTPUT 81
52
53/* display information for one message */
54
55void print_mail_info(char * prefix, mailmessage * msg)
56{
57 char * from;
58 char * subject;
59 char * decoded_from;
60 char * decoded_subject;
61 size_t cur_token;
62 int r;
63 int is_addr;
64 char * dsp_from;
65 char * dsp_subject;
66 char output[MAX_OUTPUT];
67 struct mailimf_single_fields single_fields;
68
69 is_addr = 0;
70 from = NULL;
71 subject = NULL;
72
73 decoded_subject = NULL;
74 decoded_from = NULL;
75
76 /* from field */
77
78 if (msg->msg_fields != NULL)
79 mailimf_single_fields_init(&single_fields, msg->msg_fields);
80 else
81 memset(&single_fields, 0, sizeof(single_fields));
82
83 get_from_value(&single_fields, &from, &is_addr);
84
85 if (from == NULL)
86 decoded_from = NULL;
87 else {
88 if (!is_addr) {
89 cur_token = 0;
90 r = mailmime_encoded_phrase_parse(DEST_CHARSET,
91 from, strlen(from),
92 &cur_token, DEST_CHARSET,
93 &decoded_from);
94 if (r != MAILIMF_NO_ERROR) {
95 decoded_from = strdup(from);
96 if (decoded_from == NULL)
97 goto err;
98 }
99 }
100 else {
101 decoded_from = strdup(from);
102 if (decoded_from == NULL) {
103 goto err;
104 }
105 }
106 }
107
108 if (decoded_from == NULL)
109 dsp_from = "";
110 else {
111 dsp_from = decoded_from;
112 strip_crlf(dsp_from);
113 }
114
115 /* subject */
116
117 if (single_fields.fld_subject != NULL)
118 subject = single_fields.fld_subject->sbj_value;
119
120 if (subject == NULL)
121 decoded_subject = NULL;
122 else {
123 cur_token = 0;
124 r = mailmime_encoded_phrase_parse(DEST_CHARSET,
125 subject, strlen(subject),
126 &cur_token, DEST_CHARSET,
127 &decoded_subject);
128 if (r != MAILIMF_NO_ERROR) {
129 decoded_subject = strdup(subject);
130 if (decoded_subject == NULL)
131 goto free_from;
132 }
133 }
134
135 if (decoded_subject == NULL)
136 dsp_subject = "";
137 else {
138 dsp_subject = decoded_subject;
139 strip_crlf(dsp_subject);
140 }
141
142 snprintf(output, MAX_OUTPUT, "%3i: %-21.21s %s%-53.53s",
143 msg->msg_index, dsp_from, prefix, dsp_subject);
144
145 printf("%s\n", output);
146
147 if (decoded_subject != NULL)
148 free(decoded_subject);
149 if (decoded_from != NULL)
150 free(decoded_from);
151
152 return;
153
154 free_from:
155 if (decoded_from)
156 free(decoded_from);
157 err:
158}
diff --git a/kmicromail/libetpan/tests/frm-common.h b/kmicromail/libetpan/tests/frm-common.h
new file mode 100644
index 0000000..c1a27c2
--- a/dev/null
+++ b/kmicromail/libetpan/tests/frm-common.h
@@ -0,0 +1,14 @@
1#ifndef FRM_COMMON_H
2
3#define FRM_COMMON_H
4
5#include <libetpan/libetpan.h>
6
7void get_from_value(struct mailimf_single_fields * fields,
8 char ** from, int * is_addr);
9
10void strip_crlf(char * str);
11
12void print_mail_info(char * prefix, mailmessage * msg);
13
14#endif
diff --git a/kmicromail/libetpan/tests/frm-simple.c b/kmicromail/libetpan/tests/frm-simple.c
new file mode 100644
index 0000000..7c3640f
--- a/dev/null
+++ b/kmicromail/libetpan/tests/frm-simple.c
@@ -0,0 +1,227 @@
1#include "option-parser.h"
2#include "frm-common.h"
3
4#include <libetpan/libetpan.h>
5
6#include <stdlib.h>
7#include <string.h>
8
9#define DEST_CHARSET "iso-8859-1"
10
11#define MAX_OUTPUT 81
12
13/* display information for one message */
14
15static void simple_print_mail_info(mailmessage * msg)
16{
17 char * from;
18 char * subject;
19 int is_addr;
20 char * dsp_from;
21 char * dsp_subject;
22 char output[MAX_OUTPUT];
23 struct mailimf_single_fields single_fields;
24
25 is_addr = 0;
26 from = NULL;
27 subject = NULL;
28
29 if (msg->msg_fields != NULL)
30 mailimf_single_fields_init(&single_fields, msg->msg_fields);
31 else
32 memset(&single_fields, 0, sizeof(single_fields));
33
34 /* from field */
35
36 get_from_value(&single_fields, &from, &is_addr);
37
38 if (from == NULL)
39 dsp_from = strdup("");
40 else
41 dsp_from = strdup(from);
42 if (dsp_from == NULL)
43 goto err;
44
45 strip_crlf(dsp_from);
46
47 /* subject */
48
49 if (single_fields.fld_subject != NULL)
50 subject = single_fields.fld_subject->sbj_value;
51
52 if (subject == NULL)
53 dsp_subject = strdup("");
54 else
55 dsp_subject = strdup(subject);
56
57 if (dsp_subject == NULL)
58 goto free_from;
59
60 strip_crlf(dsp_subject);
61
62 snprintf(output, MAX_OUTPUT, "%3i: %-21.21s %-53.53s\n",
63 msg->msg_index % 1000, dsp_from, dsp_subject);
64
65 printf("%s\n", output);
66
67 free(dsp_subject);
68 free(dsp_from);
69
70 return;
71
72 free_from:
73 free(dsp_from);
74 err:
75}
76
77/* get the message list and display it */
78
79static void print_message_list(mailsession * session)
80{
81 int r;
82 uint32_t i;
83 struct mailmessage_list * env_list;
84 unsigned int count;
85
86 /* get the list of messages numbers of the folder */
87
88 r = mailsession_get_messages_list(session, &env_list);
89 if (r != MAIL_NO_ERROR) {
90 printf("error message list\n");
91 goto err;
92 }
93
94 /* get fields content of these messages */
95
96 r = mailsession_get_envelopes_list(session, env_list);
97 if (r != MAIL_NO_ERROR) {
98 printf("error envelopes list\n");
99 goto free_msg_list;
100 }
101
102 /* display all the messages */
103
104 count = 0;
105 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
106 mailmessage * msg;
107
108 msg = carray_get(env_list->msg_tab, i);
109
110 if (msg->msg_fields == NULL) {
111 printf("could not fetch envelope of message %i\n", i);
112 }
113 else {
114 simple_print_mail_info(msg);
115 count ++;
116 }
117 }
118 printf(" %i messages\n", count);
119
120 /* free structure */
121
122 mailmessage_list_free(env_list);
123
124 return;
125
126 free_msg_list:
127 mailmessage_list_free(env_list);
128 err:
129}
130
131int main(int argc, char ** argv)
132{
133 int r;
134 int driver;
135 char * server;
136 int port;
137 int connection_type;
138 char * user;
139 char * password;
140 int auth_type;
141 char * path;
142 char * cache_directory;
143 char * flags_directory;
144 struct mailstorage * storage;
145 int cached;
146 struct mailfolder * folder;
147
148 /* get options */
149
150 r = parse_options(argc, argv,
151 &driver, &server, &port, &connection_type,
152 &user, &password, &auth_type,
153 &path, &cache_directory, &flags_directory);
154
155 cached = (cache_directory != NULL);
156
157 /* build the storage structure */
158
159 storage = mailstorage_new(NULL);
160 if (storage == NULL) {
161 printf("error initializing storage\n");
162 goto free_opt;
163 }
164
165 r = init_storage(storage, driver, server, port, connection_type,
166 user, password, auth_type, path, cache_directory, flags_directory);
167 if (r != MAIL_NO_ERROR) {
168 printf("error initializing storage\n");
169 goto free_opt;
170 }
171
172 /* get the folder structure */
173
174 folder = mailfolder_new(storage, path, NULL);
175 if (folder == NULL) {
176 printf("error initializing folder\n");
177 goto free_storage;
178 }
179
180 r = mailfolder_connect(folder);
181 if (r != MAIL_NO_ERROR) {
182 printf("error initializing folder\n");
183 goto free_folder;
184 }
185
186 /* get and display the list of messages */
187
188 print_message_list(folder->fld_session);
189
190 mailfolder_free(folder);
191 mailstorage_free(storage);
192
193 if (server != NULL)
194 free(server);
195 if (user != NULL)
196 free(user);
197 if (password != NULL)
198 free(password);
199 if (path != NULL)
200 free(path);
201 if (cache_directory != NULL)
202 free(cache_directory);
203 if (flags_directory != NULL)
204 free(flags_directory);
205
206 return 0;
207
208 free_folder:
209 mailfolder_free(folder);
210 free_storage:
211 mailstorage_free(storage);
212 free_opt:
213 if (server != NULL)
214 free(server);
215 if (user != NULL)
216 free(user);
217 if (password != NULL)
218 free(password);
219 if (path != NULL)
220 free(path);
221 if (cache_directory != NULL)
222 free(cache_directory);
223 if (flags_directory != NULL)
224 free(flags_directory);
225 return -1;
226}
227
diff --git a/kmicromail/libetpan/tests/frm-tree.c b/kmicromail/libetpan/tests/frm-tree.c
new file mode 100644
index 0000000..3a8464a
--- a/dev/null
+++ b/kmicromail/libetpan/tests/frm-tree.c
@@ -0,0 +1,234 @@
1#include "option-parser.h"
2#include "frm-common.h"
3
4#include <libetpan/libetpan.h>
5
6#include <stdlib.h>
7#include <string.h>
8
9#define DEST_CHARSET "iso-8859-1"
10
11/* display tree */
12
13static void
14display_sub_tree(MMAPString * prefix,
15 struct mailmessage_tree * msg_tree,
16 int level, int has_next, unsigned int * pcount)
17{
18 carray * list;
19 uint32_t cur;
20
21 if (msg_tree->node_msg != NULL) {
22 print_mail_info(prefix->str, msg_tree->node_msg);
23 (* pcount) ++;
24 }
25
26 list = msg_tree->node_children;
27
28 if (carray_count(list) != 0) {
29 char old_prefix[2];
30
31 if (level > 1) {
32 memcpy(old_prefix, prefix->str + prefix->len - 2, 2);
33 if (has_next)
34 memcpy(prefix->str + prefix->len - 2, "| ", 2);
35 else
36 memcpy(prefix->str + prefix->len - 2, " ", 2);
37 }
38 for(cur = 0 ; cur < carray_count(list) ; cur ++) {
39 int sub_has_next;
40
41 if (cur != carray_count(list) - 1) {
42 if (level > 0) {
43 if (mmap_string_append(prefix, "+-") == NULL)
44 return;
45 }
46 sub_has_next = 1;
47 }
48 else {
49 if (level > 0) {
50 if (mmap_string_append(prefix, "\\-") == NULL)
51 return;
52 }
53 sub_has_next = 0;
54 }
55
56 display_sub_tree(prefix, carray_get(list, cur),
57 level + 1, sub_has_next, pcount);
58
59 if (mmap_string_truncate(prefix, prefix->len - 2) == NULL) {
60 return;
61 }
62 }
63 if (level > 1) {
64 memcpy(prefix->str + prefix->len - 2, old_prefix, 2);
65 }
66 }
67}
68
69static void display_tree(struct mailmessage_tree * env_tree,
70 unsigned int * pcount)
71{
72 MMAPString * prefix;
73
74 prefix = mmap_string_new("");
75 if (prefix == NULL)
76 return;
77
78 display_sub_tree(prefix, env_tree, 0, 0, pcount);
79
80 mmap_string_free(prefix);
81}
82
83/* get the message list and display it */
84
85static void print_message_list(mailsession * session)
86{
87 int r;
88 struct mailmessage_list * env_list;
89 struct mailmessage_tree * env_tree;
90 unsigned int count;
91
92 /* get the list of messages numbers of the folder */
93
94 r = mailsession_get_messages_list(session, &env_list);
95 if (r != MAIL_NO_ERROR) {
96 printf("error message list\n");
97 goto err;
98 }
99
100 /* get fields content of these messages */
101
102 r = mailsession_get_envelopes_list(session, env_list);
103 if (r != MAIL_NO_ERROR) {
104 printf("error envelopes list\n");
105 goto free_msg_list;
106 }
107
108 /* build threads */
109
110 r = mail_build_thread(MAIL_THREAD_REFERENCES_NO_SUBJECT,
111 DEST_CHARSET,
112 env_list, &env_tree,
113 mailthread_tree_timecomp);
114 if (r != MAIL_NO_ERROR) {
115 printf("can't build tree\n");
116 goto free_msg_list;
117 }
118
119 /* display message tree */
120
121 count = 0;
122 display_tree(env_tree, &count);
123
124 printf(" %i messages\n", count);
125
126 /* free structure */
127
128 mailmessage_tree_free_recursive(env_tree);
129 mailmessage_list_free(env_list);
130
131 return;
132
133 free_msg_list:
134 mailmessage_list_free(env_list);
135 err:
136}
137
138int main(int argc, char ** argv)
139{
140 int r;
141 int driver;
142 char * server;
143 int port;
144 int connection_type;
145 char * user;
146 char * password;
147 int auth_type;
148 char * path;
149 char * cache_directory;
150 char * flags_directory;
151 struct mailstorage * storage;
152 int cached;
153 struct mailfolder * folder;
154
155 /* get options */
156
157 r = parse_options(argc, argv,
158 &driver, &server, &port, &connection_type,
159 &user, &password, &auth_type,
160 &path, &cache_directory, &flags_directory);
161
162 cached = (cache_directory != NULL);
163
164 /* build the storage structure */
165
166 storage = mailstorage_new(NULL);
167 if (storage == NULL) {
168 printf("error initializing storage\n");
169 goto free_opt;
170 }
171
172 r = init_storage(storage, driver, server, port, connection_type,
173 user, password, auth_type, path, cache_directory, flags_directory);
174 if (r != MAIL_NO_ERROR) {
175 printf("error initializing storage\n");
176 goto free_opt;
177 }
178
179 /* get the folder structure */
180
181 folder = mailfolder_new(storage, path, NULL);
182 if (folder == NULL) {
183 printf("error initializing folder\n");
184 goto free_storage;
185 }
186
187 r = mailfolder_connect(folder);
188 if (r != MAIL_NO_ERROR) {
189 printf("error initializing folder\n");
190 goto free_folder;
191 }
192
193 /* get and display the list of messages */
194
195 print_message_list(folder->fld_session);
196
197 mailfolder_free(folder);
198 mailstorage_free(storage);
199
200 if (server != NULL)
201 free(server);
202 if (user != NULL)
203 free(user);
204 if (password != NULL)
205 free(password);
206 if (path != NULL)
207 free(path);
208 if (cache_directory != NULL)
209 free(cache_directory);
210 if (flags_directory != NULL)
211 free(flags_directory);
212
213 return 0;
214
215 free_folder:
216 mailfolder_free(folder);
217 free_storage:
218 mailstorage_free(storage);
219 free_opt:
220 if (server != NULL)
221 free(server);
222 if (user != NULL)
223 free(user);
224 if (password != NULL)
225 free(password);
226 if (path != NULL)
227 free(path);
228 if (cache_directory != NULL)
229 free(cache_directory);
230 if (flags_directory != NULL)
231 free(flags_directory);
232 return -1;
233}
234
diff --git a/kmicromail/libetpan/tests/frm.c b/kmicromail/libetpan/tests/frm.c
new file mode 100644
index 0000000..8ce9d9b
--- a/dev/null
+++ b/kmicromail/libetpan/tests/frm.c
@@ -0,0 +1,158 @@
1#include "option-parser.h"
2#include "frm-common.h"
3
4#include <libetpan/libetpan.h>
5
6#include <stdlib.h>
7#include <string.h>
8
9#define DEST_CHARSET "iso-8859-1"
10
11/* get the message list and display it */
12
13static void print_message_list(mailsession * session)
14{
15 int r;
16 uint32_t i;
17 struct mailmessage_list * env_list;
18 unsigned int count;
19
20 /* get the list of messages numbers of the folder */
21
22 r = mailsession_get_messages_list(session, &env_list);
23 if (r != MAIL_NO_ERROR) {
24 printf("error message list\n");
25 goto err;
26 }
27
28 /* get fields content of these messages */
29
30 r = mailsession_get_envelopes_list(session, env_list);
31 if (r != MAIL_NO_ERROR) {
32 printf("error envelopes list\n");
33 goto free_msg_list;
34 }
35
36 /* display all the messages */
37
38 count = 0;
39 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
40 mailmessage * msg;
41
42 msg = carray_get(env_list->msg_tab, i);
43
44 if (msg->msg_fields == NULL) {
45 printf("could not fetch envelope of message %i\n", i);
46 }
47 else {
48 print_mail_info("", msg);
49 count ++;
50 }
51 }
52 printf(" %i messages\n", count);
53
54 /* free structure */
55
56 mailmessage_list_free(env_list);
57
58 return;
59
60 free_msg_list:
61 mailmessage_list_free(env_list);
62 err:
63}
64
65int main(int argc, char ** argv)
66{
67 int r;
68 int driver;
69 char * server;
70 int port;
71 int connection_type;
72 char * user;
73 char * password;
74 int auth_type;
75 char * path;
76 char * cache_directory;
77 char * flags_directory;
78 struct mailstorage * storage;
79 struct mailfolder * folder;
80
81 /* get options */
82
83 r = parse_options(argc, argv,
84 &driver, &server, &port, &connection_type,
85 &user, &password, &auth_type,
86 &path, &cache_directory, &flags_directory);
87
88 /* build the storage structure */
89
90 storage = mailstorage_new(NULL);
91 if (storage == NULL) {
92 printf("error initializing storage\n");
93 goto free_opt;
94 }
95
96 r = init_storage(storage, driver, server, port, connection_type,
97 user, password, auth_type, path, cache_directory, flags_directory);
98 if (r != MAIL_NO_ERROR) {
99 printf("error initializing storage\n");
100 goto free_opt;
101 }
102
103 /* get the folder structure */
104
105 folder = mailfolder_new(storage, path, NULL);
106 if (folder == NULL) {
107 printf("error initializing folder\n");
108 goto free_storage;
109 }
110
111 r = mailfolder_connect(folder);
112 if (r != MAIL_NO_ERROR) {
113 printf("error connecting folder\n");
114 goto free_folder;
115 }
116
117 /* get and display the list of messages */
118
119 print_message_list(folder->fld_session);
120
121 mailfolder_free(folder);
122 mailstorage_free(storage);
123
124 if (server != NULL)
125 free(server);
126 if (user != NULL)
127 free(user);
128 if (password != NULL)
129 free(password);
130 if (path != NULL)
131 free(path);
132 if (cache_directory != NULL)
133 free(cache_directory);
134 if (flags_directory != NULL)
135 free(flags_directory);
136
137 return 0;
138
139 free_folder:
140 mailfolder_free(folder);
141 free_storage:
142 mailstorage_free(storage);
143 free_opt:
144 if (server != NULL)
145 free(server);
146 if (user != NULL)
147 free(user);
148 if (password != NULL)
149 free(password);
150 if (path != NULL)
151 free(path);
152 if (cache_directory != NULL)
153 free(cache_directory);
154 if (flags_directory != NULL)
155 free(flags_directory);
156 return -1;
157}
158
diff --git a/kmicromail/libetpan/tests/option-parser.c b/kmicromail/libetpan/tests/option-parser.c
new file mode 100644
index 0000000..57a1597
--- a/dev/null
+++ b/kmicromail/libetpan/tests/option-parser.c
@@ -0,0 +1,234 @@
1#define _GNU_SOURCE
2#include <getopt.h>
3
4#include <stdlib.h>
5#include <string.h>
6#include <limits.h>
7
8#include <libetpan/libetpan.h>
9
10#include "option-parser.h"
11
12/*
13 options
14
15 --driver (pop3|imap|nntp|mbox|mh|maildir) -d
16
17 default driver is mbox
18
19 --server {server-name} -s
20 --port {port-number} -p
21 --tls -t
22 --starttls -x
23 --user {login} -u
24 --password {password} -v
25 --path {mailbox} -l
26 --apop -a
27 --cache {directory} -c
28 --flags {directory} -f
29*/
30
31struct storage_name {
32 int id;
33 char * name;
34};
35
36static struct storage_name storage_tab[] = {
37 {POP3_STORAGE, "pop3"},
38 {IMAP_STORAGE, "imap"},
39 {NNTP_STORAGE, "nntp"},
40 {MBOX_STORAGE, "mbox"},
41 {MH_STORAGE, "mh"},
42 {MAILDIR_STORAGE, "maildir"},
43};
44
45static int get_driver(char * name)
46{
47 int driver_type;
48 unsigned int i;
49
50 driver_type = -1;
51 for(i = 0 ; i < sizeof(storage_tab) / sizeof(struct storage_name) ; i++) {
52 if (strcasecmp(name, storage_tab[i].name) == 0) {
53 driver_type = i;
54 break;
55 }
56 }
57
58 return driver_type;
59}
60
61int parse_options(int argc, char ** argv,
62 int * driver,
63 char ** server, int * port, int * connection_type,
64 char ** user, char ** password, int * auth_type,
65 char ** path, char ** cache_directory,
66 char ** flags_directory)
67{
68 int index;
69 static struct option long_options[] = {
70 {"driver", 1, 0, 'd'},
71 {"server", 1, 0, 's'},
72 {"port", 1, 0, 'p'},
73 {"tls", 0, 0, 't'},
74 {"starttls", 0, 0, 'x'},
75 {"user", 1, 0, 'u'},
76 {"password", 1, 0, 'v'},
77 {"path", 1, 0, 'l'},
78 {"apop", 0, 0, 'a'},
79 {"cache", 1, 0, 'c'},
80 {"flags", 1, 0, 'f'},
81 };
82 int r;
83 char location[PATH_MAX];
84 char * env_user;
85
86 index = 0;
87
88 * driver = MBOX_STORAGE;
89 * server = NULL;
90 * port = 0;
91 * connection_type = CONNECTION_TYPE_PLAIN;
92 * user = NULL;
93 * password = NULL;
94 * auth_type = POP3_AUTH_TYPE_PLAIN;
95 env_user = getenv("USER");
96 if (env_user != NULL) {
97 snprintf(location, PATH_MAX, "/var/mail/%s", env_user);
98 * path = strdup(location);
99 }
100 else
101 * path = NULL;
102 * cache_directory = NULL;
103 * flags_directory = NULL;
104
105 while (1) {
106 r = getopt_long(argc, argv, "d:s:p:txu:v:l:ac:f:", long_options, &index);
107
108 if (r == -1)
109 break;
110
111 switch (r) {
112 case 'd':
113 * driver = get_driver(optarg);
114 break;
115 case 's':
116 if (* server != NULL)
117 free(* server);
118 * server = strdup(optarg);
119 break;
120 case 'p':
121 * port = strtoul(optarg, NULL, 10);
122 break;
123 case 't':
124 * connection_type = CONNECTION_TYPE_TLS;
125 break;
126 case 'x':
127 * connection_type = CONNECTION_TYPE_STARTTLS;
128 break;
129 case 'u':
130 if (* user != NULL)
131 free(* user);
132 * user = strdup(optarg);
133 break;
134 case 'v':
135 if (* password != NULL)
136 free(* password);
137 * password = strdup(optarg);
138 break;
139 case 'l':
140 if (* path != NULL)
141 free(* path);
142 * path = strdup(optarg);
143 break;
144 case 'a':
145 * auth_type = POP3_AUTH_TYPE_APOP;
146 break;
147 case 'c':
148 if (* cache_directory != NULL)
149 free(* cache_directory);
150 * cache_directory = strdup(optarg);
151 break;
152 case 'f':
153 if (* flags_directory != NULL)
154 free(* flags_directory);
155 * flags_directory = strdup(optarg);
156 break;
157 }
158 }
159
160 return 0;
161}
162
163int init_storage(struct mailstorage * storage,
164 int driver, char * server, int port,
165 int connection_type, char * user, char * password, int auth_type,
166 char * path, char * cache_directory, char * flags_directory)
167{
168 int r;
169 int cached;
170
171 cached = (cache_directory != NULL);
172
173 switch (driver) {
174 case POP3_STORAGE:
175 r = pop3_mailstorage_init(storage, server, port, NULL, connection_type,
176 auth_type, user, password, cached, cache_directory,
177 flags_directory);
178 if (r != MAIL_NO_ERROR) {
179 printf("error initializing POP3 storage\n");
180 goto err;
181 }
182 break;
183
184 case IMAP_STORAGE:
185 r = imap_mailstorage_init(storage, server, port, NULL, connection_type,
186 IMAP_AUTH_TYPE_PLAIN, user, password, cached, cache_directory);
187 if (r != MAIL_NO_ERROR) {
188 printf("error initializing IMAP storage\n");
189 goto err;
190 }
191 break;
192
193 case NNTP_STORAGE:
194 r = nntp_mailstorage_init(storage, server, port, NULL, connection_type,
195 NNTP_AUTH_TYPE_PLAIN, user, password, cached, cache_directory,
196 flags_directory);
197 if (r != MAIL_NO_ERROR) {
198 printf("error initializing NNTP storage\n");
199 goto err;
200 }
201 break;
202
203 case MBOX_STORAGE:
204 r = mbox_mailstorage_init(storage, path, cached, cache_directory,
205 flags_directory);
206 if (r != MAIL_NO_ERROR) {
207 printf("error initializing mbox storage\n");
208 goto err;
209 }
210 break;
211
212 case MH_STORAGE:
213 r = mh_mailstorage_init(storage, path, cached, cache_directory,
214 flags_directory);
215 if (r != MAIL_NO_ERROR) {
216 printf("error initializing MH storage\n");
217 goto err;
218 }
219 break;
220 case MAILDIR_STORAGE:
221 r = maildir_mailstorage_init(storage, path, cached, cache_directory,
222 flags_directory);
223 if (r != MAIL_NO_ERROR) {
224 printf("error initializing maildir storage\n");
225 goto err;
226 }
227 break;
228 }
229
230 return MAIL_NO_ERROR;
231
232 err:
233 return r;
234}
diff --git a/kmicromail/libetpan/tests/option-parser.h b/kmicromail/libetpan/tests/option-parser.h
new file mode 100644
index 0000000..d765332
--- a/dev/null
+++ b/kmicromail/libetpan/tests/option-parser.h
@@ -0,0 +1,28 @@
1#ifndef OPTION_PARSER
2
3#define OPTION_PARSER
4
5#include <libetpan/libetpan.h>
6
7enum {
8 POP3_STORAGE = 0,
9 IMAP_STORAGE,
10 NNTP_STORAGE,
11 MBOX_STORAGE,
12 MH_STORAGE,
13 MAILDIR_STORAGE,
14};
15
16int parse_options(int argc, char ** argv,
17 int * driver,
18 char ** server, int * port, int * connection_type,
19 char ** user, char ** password, int * auth_type,
20 char ** path, char ** cache_directory,
21 char ** flags_directory);
22
23int init_storage(struct mailstorage * storage,
24 int driver, char * server, int port,
25 int connection_type, char * user, char * password, int auth_type,
26 char * path, char * cache_directory, char * flags_directory);
27
28#endif
diff --git a/kmicromail/libetpan/tests/readmsg-common.c b/kmicromail/libetpan/tests/readmsg-common.c
new file mode 100644
index 0000000..060497d
--- a/dev/null
+++ b/kmicromail/libetpan/tests/readmsg-common.c
@@ -0,0 +1,720 @@
1#include "readmsg-common.h"
2
3#include <sys/stat.h>
4#include <sys/mman.h>
5#include <fcntl.h>
6#include <unistd.h>
7#include <string.h>
8#include <stdlib.h>
9
10/* returns TRUE is given MIME part is a text part */
11
12int etpan_mime_is_text(struct mailmime * build_info)
13{
14 if (build_info->mm_type == MAILMIME_SINGLE) {
15 if (build_info->mm_content_type != NULL) {
16 if (build_info->mm_content_type->ct_type->tp_type ==
17 MAILMIME_TYPE_DISCRETE_TYPE) {
18 if (build_info->mm_content_type->ct_type->tp_data.tp_discrete_type->dt_type ==
19 MAILMIME_DISCRETE_TYPE_TEXT)
20 return 1;
21 }
22 }
23 else
24 return 1;
25 }
26
27 return 0;
28}
29
30
31/* display content type */
32
33int show_part_info(FILE * f,
34 struct mailmime_single_fields * mime_fields,
35 struct mailmime_content * content)
36{
37 char * description;
38 char * filename;
39 int col;
40 int r;
41
42 description = mime_fields->fld_description;
43 filename = mime_fields->fld_disposition_filename;
44
45 col = 0;
46
47 r = fprintf(f, " [ Part ");
48 if (r < 0)
49 goto err;
50
51 if (content != NULL) {
52 r = mailmime_content_type_write(f, &col, content);
53 if (r != MAILIMF_NO_ERROR)
54 goto err;
55 }
56
57 if (filename != NULL) {
58 r = fprintf(f, " (%s)", filename);
59 if (r < 0)
60 goto err;
61 }
62
63 if (description != NULL) {
64 r = fprintf(f, " : %s", description);
65 if (r < 0)
66 goto err;
67 }
68
69 r = fprintf(f, " ]\n\n");
70 if (r < 0)
71 goto err;
72
73 return NO_ERROR;
74
75 err:
76 return ERROR_FILE;
77}
78
79/*
80 fetch the data of the mailmime_data structure whether it is a file
81 or a string.
82
83 data must be freed with mmap_string_unref()
84*/
85
86#if 0
87static int fetch_data(struct mailmime_data * data,
88 char ** result, size_t * result_len)
89{
90 int fd;
91 int r;
92 char * text;
93 struct stat buf;
94 int res;
95 MMAPString * mmapstr;
96
97 switch (data->dt_type) {
98 case MAILMIME_DATA_TEXT:
99 mmapstr = mmap_string_new_len(data->dt_data.dt_text.dt_data,
100 data->dt_data.dt_text.dt_length);
101 if (mmapstr == NULL) {
102 res = ERROR_MEMORY;
103 goto err;
104 }
105
106 * result = mmapstr->str;
107 * result_len = mmapstr->len;
108
109 return NO_ERROR;
110
111 case MAILMIME_DATA_FILE:
112 fd = open(data->dt_data.dt_filename, O_RDONLY);
113 if (fd < 0) {
114 res = ERROR_FILE;
115 goto err;
116 }
117
118 r = fstat(fd, &buf);
119 if (r < 0) {
120 res = ERROR_FILE;
121 goto close;
122 }
123
124 if (buf.st_size != 0) {
125 text = mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
126 if (text == MAP_FAILED) {
127 res = ERROR_FILE;
128 goto close;
129 }
130
131 mmapstr = mmap_string_new_len(text, buf.st_size);
132 if (mmapstr == NULL) {
133 res = r;
134 goto unmap;
135 }
136
137 munmap(text, buf.st_size);
138 }
139 else {
140 mmapstr = mmap_string_new("");
141 if (mmapstr == NULL) {
142 res = r;
143 goto close;
144 }
145 }
146
147 close(fd);
148
149 * result = mmapstr->str;
150 * result_len = mmapstr->len;
151
152 return NO_ERROR;
153
154 default:
155 return ERROR_INVAL;
156 }
157
158 unmap:
159 munmap(text, buf.st_size);
160 close:
161 close(fd);
162 err:
163 return res;
164}
165#endif
166
167/* fetch message and decode if it is base64 or quoted-printable */
168
169int etpan_fetch_message(mailmessage * msg_info,
170 struct mailmime * mime_part,
171 struct mailmime_single_fields * fields,
172 char ** result, size_t * result_len)
173{
174 char * data;
175 size_t len;
176 int r;
177 int encoding;
178 char * decoded;
179 size_t decoded_len;
180 size_t cur_token;
181 int res;
182 int encoded;
183
184 encoded = 0;
185
186 r = mailmessage_fetch_section(msg_info,
187 mime_part, &data, &len);
188 if (r != MAIL_NO_ERROR) {
189 res = ERROR_FETCH;
190 goto err;
191 }
192
193 encoded = 1;
194
195 /* decode message */
196
197 if (encoded) {
198 if (fields->fld_encoding != NULL)
199 encoding = fields->fld_encoding->enc_type;
200 else
201 encoding = MAILMIME_MECHANISM_8BIT;
202 }
203 else {
204 encoding = MAILMIME_MECHANISM_8BIT;
205 }
206
207 cur_token = 0;
208 r = mailmime_part_parse(data, len, &cur_token,
209 encoding, &decoded, &decoded_len);
210 if (r != MAILIMF_NO_ERROR) {
211 res = ERROR_FETCH;
212 goto free;
213 }
214
215 mailmessage_fetch_result_free(msg_info, data);
216
217 * result = decoded;
218 * result_len = decoded_len;
219
220 return NO_ERROR;
221
222 free:
223 mailmessage_fetch_result_free(msg_info, data);
224 err:
225 return res;
226}
227
228
229/* fetch fields */
230
231struct mailimf_fields * fetch_fields(mailmessage * msg_info,
232 struct mailmime * mime)
233{
234 char * data;
235 size_t len;
236 int r;
237 size_t cur_token;
238 struct mailimf_fields * fields;
239
240 r = mailmessage_fetch_section_header(msg_info, mime, &data, &len);
241 if (r != MAIL_NO_ERROR)
242 return NULL;
243
244 cur_token = 0;
245 r = mailimf_fields_parse(data, len, &cur_token, &fields);
246 if (r != MAILIMF_NO_ERROR) {
247 mailmessage_fetch_result_free(msg_info, data);
248 return NULL;
249 }
250
251 mailmessage_fetch_result_free(msg_info, data);
252
253 return fields;
254}
255
256
257
258#define MAX_MAIL_COL 72
259
260/* write decoded mailbox */
261
262static int
263etpan_mailbox_write(FILE * f, int * col,
264 struct mailimf_mailbox * mb)
265{
266 int r;
267
268 if (* col > 1) {
269
270 if (* col + strlen(mb->mb_addr_spec) >= MAX_MAIL_COL) {
271 r = mailimf_string_write(f, col, "\r\n ", 3);
272 if (r != MAILIMF_NO_ERROR)
273 return ERROR_FILE;
274 * col = 1;
275 }
276 }
277
278 if (mb->mb_display_name) {
279 char * decoded_from;
280 size_t cur_token;
281
282 cur_token = 0;
283 r = mailmime_encoded_phrase_parse(DEST_CHARSET,
284 mb->mb_display_name, strlen(mb->mb_display_name),
285 &cur_token, DEST_CHARSET,
286 &decoded_from);
287 if (r != MAILIMF_NO_ERROR) {
288 decoded_from = strdup(mb->mb_display_name);
289 if (decoded_from == NULL)
290 return ERROR_MEMORY;
291 }
292
293 r = mailimf_quoted_string_write(f, col, decoded_from,
294 strlen(decoded_from));
295 if (r != MAILIMF_NO_ERROR) {
296 free(decoded_from);
297 return ERROR_FILE;
298 }
299
300 if (* col > 1) {
301
302 if (* col + strlen(decoded_from) + 3 >= MAX_MAIL_COL) {
303 r = mailimf_string_write(f, col, "\r\n ", 3);
304 if (r != MAILIMF_NO_ERROR) {
305 free(decoded_from);
306 return r;
307 }
308 * col = 1;
309 }
310 }
311
312 free(decoded_from);
313
314 r = mailimf_string_write(f, col, " <", 2);
315 if (r != MAILIMF_NO_ERROR)
316 return ERROR_FILE;
317
318 r = mailimf_string_write(f, col,
319 mb->mb_addr_spec, strlen(mb->mb_addr_spec));
320 if (r != MAILIMF_NO_ERROR)
321 return ERROR_FILE;
322
323 r = mailimf_string_write(f, col, ">", 1);
324 if (r != MAILIMF_NO_ERROR)
325 return ERROR_FILE;
326 }
327 else {
328 r = mailimf_string_write(f, col,
329 mb->mb_addr_spec, strlen(mb->mb_addr_spec));
330 if (r != MAILIMF_NO_ERROR)
331 return ERROR_FILE;
332 }
333
334
335 return NO_ERROR;
336
337}
338
339/* write decoded mailbox list */
340
341int
342etpan_mailbox_list_write(FILE * f, int * col,
343 struct mailimf_mailbox_list * mb_list)
344{
345 clistiter * cur;
346 int r;
347 int first;
348
349 first = 1;
350
351 for(cur = clist_begin(mb_list->mb_list) ; cur != NULL ;
352 cur = clist_next(cur)) {
353 struct mailimf_mailbox * mb;
354
355 mb = cur->data;
356
357 if (!first) {
358 r = mailimf_string_write(f, col, ", ", 2);
359 if (r != MAILIMF_NO_ERROR)
360 return ERROR_FILE;
361 }
362 else {
363 first = 0;
364 }
365
366 r = etpan_mailbox_write(f, col, mb);
367 if (r != NO_ERROR)
368 return r;
369 }
370
371 return NO_ERROR;
372}
373
374/* write decoded group */
375
376static int
377etpan_group_write(FILE * f, int * col,
378 struct mailimf_group * group)
379{
380 int r;
381
382 r = mailimf_string_write(f, col, group->grp_display_name,
383 strlen(group->grp_display_name));
384 if (r != MAILIMF_NO_ERROR)
385 return ERROR_FILE;
386
387 r = mailimf_string_write(f, col, ": ", 2);
388 if (r != MAILIMF_NO_ERROR)
389 return ERROR_FILE;
390
391 if (group->grp_mb_list != NULL) {
392 r = etpan_mailbox_list_write(f, col, group->grp_mb_list);
393 if (r != NO_ERROR)
394 return r;
395 }
396
397 r = mailimf_string_write(f, col, ";", 1);
398 if (r != MAILIMF_NO_ERROR)
399 return ERROR_FILE;
400
401 return NO_ERROR;
402}
403
404/* write decoded address */
405
406int
407etpan_address_write(FILE * f, int * col,
408 struct mailimf_address * addr)
409{
410 int r;
411
412 switch(addr->ad_type) {
413 case MAILIMF_ADDRESS_MAILBOX:
414 r = etpan_mailbox_write(f, col, addr->ad_data.ad_mailbox);
415 if (r != NO_ERROR)
416 return r;
417
418 break;
419
420 case MAILIMF_ADDRESS_GROUP:
421 r = etpan_group_write(f, col, addr->ad_data.ad_group);
422 if (r != NO_ERROR)
423 return r;
424
425 break;
426 }
427
428 return MAILIMF_NO_ERROR;
429}
430
431/* write decoded address list */
432
433int
434etpan_address_list_write(FILE * f, int * col,
435 struct mailimf_address_list * addr_list)
436{
437 clistiter * cur;
438 int r;
439 int first;
440
441 first = 1;
442
443 for(cur = clist_begin(addr_list->ad_list) ; cur != NULL ;
444 cur = clist_next(cur)) {
445 struct mailimf_address * addr;
446
447 addr = clist_content(cur);
448
449 if (!first) {
450 r = mailimf_string_write(f, col, ", ", 2);
451 if (r != MAILIMF_NO_ERROR)
452 return ERROR_FILE;
453 }
454 else {
455 first = 0;
456 }
457
458 r = etpan_address_write(f, col, addr);
459 if (r != NO_ERROR)
460 return r;
461 }
462
463 return NO_ERROR;
464}
465
466/* write decoded subject */
467
468static int etpan_subject_write(FILE * f, int * col,
469 char * subject)
470{
471 int r;
472 char * decoded_subject;
473 size_t cur_token;
474
475 r = mailimf_string_write(f, col, "Subject: ", 9);
476 if (r != MAILIMF_NO_ERROR) {
477 return ERROR_FILE;
478 }
479
480 cur_token = 0;
481 r = mailmime_encoded_phrase_parse(DEST_CHARSET,
482 subject, strlen(subject),
483 &cur_token, DEST_CHARSET,
484 &decoded_subject);
485 if (r != MAILIMF_NO_ERROR) {
486 decoded_subject = strdup(subject);
487 if (decoded_subject == NULL)
488 return ERROR_MEMORY;
489 }
490
491 r = mailimf_string_write(f, col, decoded_subject, strlen(decoded_subject));
492 if (r != MAILIMF_NO_ERROR) {
493 free(decoded_subject);
494 return ERROR_FILE;
495 }
496
497 free(decoded_subject);
498
499 r = mailimf_string_write(f, col, "\r\n", 2);
500 if (r != MAILIMF_NO_ERROR) {
501 return ERROR_FILE;
502 }
503 * col = 0;
504
505 return NO_ERROR;
506}
507
508/* write decoded fields */
509
510int fields_write(FILE * f, int * col,
511 struct mailimf_fields * fields)
512{
513 clistiter * cur;
514 int r;
515
516 for(cur = clist_begin(fields->fld_list) ; cur != NULL ;
517 cur = clist_next(cur)) {
518 struct mailimf_field * field;
519
520 field = clist_content(cur);
521
522 switch (field->fld_type) {
523 case MAILIMF_FIELD_FROM:
524 r = mailimf_string_write(f, col, "From: ", 6);
525 if (r != MAILIMF_NO_ERROR)
526 goto err;
527
528 r = etpan_mailbox_list_write(f, col,
529 field->fld_data.fld_from->frm_mb_list);
530 if (r != NO_ERROR)
531 goto err;
532
533 r = mailimf_string_write(f, col, "\r\n", 2);
534 if (r != MAILIMF_NO_ERROR)
535 goto err;
536 * col = 0;
537
538 break;
539
540 case MAILIMF_FIELD_REPLY_TO:
541 r = mailimf_string_write(f, col, "Reply-To: ", 10);
542 if (r != MAILIMF_NO_ERROR)
543 goto err;
544
545 r = etpan_address_list_write(f, col,
546 field->fld_data.fld_reply_to->rt_addr_list);
547 if (r != NO_ERROR)
548 goto err;
549
550 r = mailimf_string_write(f, col, "\r\n", 2);
551 if (r != MAILIMF_NO_ERROR)
552 goto err;
553 * col = 0;
554
555 break;
556
557 case MAILIMF_FIELD_TO:
558 r = mailimf_string_write(f, col, "To: ", 4);
559 if (r != MAILIMF_NO_ERROR)
560 goto err;
561
562 r = etpan_address_list_write(f, col,
563 field->fld_data.fld_to->to_addr_list);
564 if (r != NO_ERROR)
565 goto err;
566
567 r = mailimf_string_write(f, col, "\r\n", 2);
568 if (r != MAILIMF_NO_ERROR)
569 goto err;
570 * col = 0;
571
572 break;
573
574 case MAILIMF_FIELD_CC:
575 r = mailimf_string_write(f, col, "Cc: ", 4);
576 if (r != MAILIMF_NO_ERROR)
577 goto err;
578
579 r = etpan_address_list_write(f, col,
580 field->fld_data.fld_cc->cc_addr_list);
581 if (r != NO_ERROR)
582 goto err;
583
584 r = mailimf_string_write(f, col, "\r\n", 2);
585 if (r != MAILIMF_NO_ERROR)
586 goto err;
587 * col = 0;
588
589 break;
590
591 case MAILIMF_FIELD_BCC:
592 r = mailimf_string_write(f, col, "Bcc: ", 10);
593 if (r != MAILIMF_NO_ERROR)
594 goto err;
595
596 if (field->fld_data.fld_bcc->bcc_addr_list != NULL) {
597 r = etpan_address_list_write(f, col,
598 field->fld_data.fld_bcc->bcc_addr_list);
599 if (r != NO_ERROR)
600 goto err;
601 }
602
603 r = mailimf_string_write(f, col, "\r\n", 2);
604 if (r != MAILIMF_NO_ERROR)
605 goto err;
606 * col = 0;
607
608 break;
609
610 case MAILIMF_FIELD_SUBJECT:
611 r = etpan_subject_write(f, col, field->fld_data.fld_subject->sbj_value);
612 if (r != MAILIMF_NO_ERROR)
613 goto err;
614 break;
615
616 case MAILIMF_FIELD_RESENT_FROM:
617 r = mailimf_string_write(f, col, "Resent-From: ", 13);
618 if (r != MAILIMF_NO_ERROR)
619 goto err;
620
621 r = etpan_mailbox_list_write(f, col,
622 field->fld_data.fld_resent_from->frm_mb_list);
623 if (r != NO_ERROR)
624 goto err;
625
626 r = mailimf_string_write(f, col, "\r\n", 2);
627 if (r != MAILIMF_NO_ERROR)
628 goto err;
629 * col = 0;
630 break;
631
632 case MAILIMF_FIELD_RESENT_TO:
633 r = mailimf_string_write(f, col, "Resent-To: ", 11);
634 if (r != MAILIMF_NO_ERROR)
635 goto err;
636
637 r = etpan_address_list_write(f, col,
638 field->fld_data.fld_resent_to->to_addr_list);
639 if (r != NO_ERROR)
640 goto err;
641
642 r = mailimf_string_write(f, col, "\r\n", 2);
643 if (r != MAILIMF_NO_ERROR)
644 goto err;
645 * col = 0;
646
647 break;
648 case MAILIMF_FIELD_RESENT_CC:
649 r = mailimf_string_write(f, col, "Resent-Cc: ", 11);
650 if (r != MAILIMF_NO_ERROR)
651 goto err;
652
653 r = etpan_address_list_write(f, col,
654 field->fld_data.fld_resent_cc->cc_addr_list);
655 if (r != NO_ERROR)
656 goto err;
657
658 r = mailimf_string_write(f, col, "\r\n", 2);
659 if (r != MAILIMF_NO_ERROR)
660 goto err;
661 * col = 0;
662
663 break;
664 case MAILIMF_FIELD_RESENT_BCC:
665 r = mailimf_string_write(f, col, "Resent-Bcc: ", 12);
666 if (r != MAILIMF_NO_ERROR)
667 goto err;
668
669 if (field->fld_data.fld_resent_bcc->bcc_addr_list != NULL) {
670 r = etpan_address_list_write(f, col,
671 field->fld_data.fld_resent_bcc->bcc_addr_list);
672 if (r != NO_ERROR)
673 goto err;
674 }
675
676 r = mailimf_string_write(f, col, "\r\n", 2);
677 if (r != MAILIMF_NO_ERROR)
678 goto err;
679 * col = 0;
680
681 break;
682
683 case MAILIMF_FIELD_ORIG_DATE:
684 case MAILIMF_FIELD_RESENT_DATE:
685 r = mailimf_field_write(f, col, field);
686 if (r != MAILIMF_NO_ERROR)
687 goto err;
688 break;
689
690 case MAILIMF_FIELD_OPTIONAL_FIELD:
691 if ((strcasecmp(field->fld_data.fld_optional_field->fld_name,
692 "X-Mailer") == 0)
693 || (strncasecmp(field->fld_data.fld_optional_field->fld_name,
694 "Resent-", 7) == 0)
695 || (strcasecmp(field->fld_data.fld_optional_field->fld_name,
696 "Newsgroups") == 0)
697 || (strcasecmp(field->fld_data.fld_optional_field->fld_name,
698 "Followup-To") == 0)
699 || (strcasecmp(field->fld_data.fld_optional_field->fld_name,
700 "User-Agent") == 0)) {
701 r = mailimf_field_write(f, col, field);
702 if (r != MAILIMF_NO_ERROR)
703 goto err;
704 }
705 break;
706
707 case MAILIMF_FIELD_MESSAGE_ID:
708 case MAILIMF_FIELD_SENDER:
709 case MAILIMF_FIELD_IN_REPLY_TO:
710 case MAILIMF_FIELD_REFERENCES:
711 default:
712 break;
713 }
714 }
715
716 return NO_ERROR;
717
718 err:
719 return ERROR_FILE;
720}
diff --git a/kmicromail/libetpan/tests/readmsg-common.h b/kmicromail/libetpan/tests/readmsg-common.h
new file mode 100644
index 0000000..70265f2
--- a/dev/null
+++ b/kmicromail/libetpan/tests/readmsg-common.h
@@ -0,0 +1,34 @@
1#ifndef READMSG_COMMON_H
2
3#define READMSG_COMMON_H
4
5#include <libetpan/libetpan.h>
6
7#define DEST_CHARSET "iso-8859-1"
8
9enum {
10 NO_ERROR,
11 ERROR_FILE,
12 ERROR_MEMORY,
13 ERROR_INVAL,
14 ERROR_FETCH,
15};
16
17int etpan_mime_is_text(struct mailmime * build_info);
18
19int show_part_info(FILE * f,
20 struct mailmime_single_fields * mime_fields,
21 struct mailmime_content * content);
22
23int etpan_fetch_message(mailmessage * msg_info,
24 struct mailmime * mime_part,
25 struct mailmime_single_fields * fields,
26 char ** result, size_t * result_len);
27
28struct mailimf_fields * fetch_fields(mailmessage * msg_info,
29 struct mailmime * mime);
30
31int fields_write(FILE * f, int * col,
32 struct mailimf_fields * fields);
33
34#endif
diff --git a/kmicromail/libetpan/tests/readmsg-simple.c b/kmicromail/libetpan/tests/readmsg-simple.c
new file mode 100644
index 0000000..ea57d6d
--- a/dev/null
+++ b/kmicromail/libetpan/tests/readmsg-simple.c
@@ -0,0 +1,133 @@
1#include <unistd.h>
2#include <string.h>
3#include <stdlib.h>
4
5#include <libetpan/libetpan.h>
6
7#include "option-parser.h"
8
9int main(int argc, char ** argv)
10{
11 int r;
12 int driver;
13 char * server;
14 int port;
15 int connection_type;
16 char * user;
17 char * password;
18 int auth_type;
19 char * path;
20 char * cache_directory;
21 char * flags_directory;
22 struct mailstorage * storage;
23 int cached;
24 struct mailfolder * folder;
25
26 /* get options */
27
28 r = parse_options(argc, argv,
29 &driver, &server, &port, &connection_type,
30 &user, &password, &auth_type,
31 &path, &cache_directory, &flags_directory);
32
33 cached = (cache_directory != NULL);
34
35 /* build the storage structure */
36
37 storage = mailstorage_new(NULL);
38 if (storage == NULL) {
39 printf("error initializing storage\n");
40 goto free_opt;
41 }
42
43 r = init_storage(storage, driver, server, port, connection_type,
44 user, password, auth_type, path, cache_directory, flags_directory);
45 if (r != MAIL_NO_ERROR) {
46 printf("error initializing storage\n");
47 goto free_opt;
48 }
49
50 /* get the folder structure */
51
52 folder = mailfolder_new(storage, path, NULL);
53 if (folder == NULL) {
54 printf("error initializing folder\n");
55 goto free_storage;
56 }
57
58 r = mailfolder_connect(folder);
59 if (r != MAIL_NO_ERROR) {
60 printf("error initializing folder\n");
61 goto free_folder;
62 }
63
64 while (optind < argc) {
65 mailmessage * msg;
66 uint32_t msg_num;
67 char * data;
68 size_t size;
69
70 msg_num = strtoul(argv[optind], NULL, 10);
71
72 r = mailsession_get_message(folder->fld_session, msg_num, &msg);
73 if (r != MAIL_NO_ERROR) {
74 printf("** message %i not found **\n", msg_num);
75 optind ++;
76 continue;
77 }
78
79 r = mailmessage_fetch(msg, &data, &size);
80 if (r != MAIL_NO_ERROR) {
81 printf("** message %i not found - %s **\n", msg_num,
82 maildriver_strerror(r));
83 mailmessage_free(msg);
84 optind ++;
85 continue;
86 }
87
88 fwrite(data, 1, size, stdout);
89
90 mailmessage_fetch_result_free(msg, data);
91
92 mailmessage_free(msg);
93
94 optind ++;
95 }
96
97 mailfolder_free(folder);
98 mailstorage_free(storage);
99
100 if (server != NULL)
101 free(server);
102 if (user != NULL)
103 free(user);
104 if (password != NULL)
105 free(password);
106 if (path != NULL)
107 free(path);
108 if (cache_directory != NULL)
109 free(cache_directory);
110 if (flags_directory != NULL)
111 free(flags_directory);
112
113 return 0;
114
115 free_folder:
116 mailfolder_free(folder);
117 free_storage:
118 mailstorage_free(storage);
119 free_opt:
120 if (server != NULL)
121 free(server);
122 if (user != NULL)
123 free(user);
124 if (password != NULL)
125 free(password);
126 if (path != NULL)
127 free(path);
128 if (cache_directory != NULL)
129 free(cache_directory);
130 if (flags_directory != NULL)
131 free(flags_directory);
132 return -1;
133}
diff --git a/kmicromail/libetpan/tests/readmsg.c b/kmicromail/libetpan/tests/readmsg.c
new file mode 100644
index 0000000..822c93c
--- a/dev/null
+++ b/kmicromail/libetpan/tests/readmsg.c
@@ -0,0 +1,355 @@
1#include <unistd.h>
2#include <string.h>
3#include <stdlib.h>
4
5#include <libetpan/charconv.h>
6#include <libetpan/libetpan.h>
7
8#include "option-parser.h"
9#include "readmsg-common.h"
10
11
12/* render message */
13
14static int etpan_render_mime(FILE * f, mailmessage * msg_info,
15 struct mailmime * mime)
16{
17 int r;
18 clistiter * cur;
19 int col;
20 int text;
21 int show;
22 struct mailmime_single_fields fields;
23 int res;
24
25 mailmime_single_fields_init(&fields, mime->mm_mime_fields,
26 mime->mm_content_type);
27
28 text = etpan_mime_is_text(mime);
29
30 r = show_part_info(f, &fields, mime->mm_content_type);
31 if (r != NO_ERROR) {
32 res = r;
33 goto err;
34 }
35
36 switch(mime->mm_type) {
37 case MAILMIME_SINGLE:
38 show = 0;
39 if (text)
40 show = 1;
41
42 if (show) {
43 char * data;
44 size_t len;
45 char * converted;
46 size_t converted_len;
47 char * source_charset;
48 size_t write_len;
49
50 /* viewable part */
51
52 r = etpan_fetch_message(msg_info, mime,
53 &fields, &data, &len);
54 if (r != NO_ERROR) {
55 res = r;
56 goto err;
57 }
58
59 source_charset = fields.fld_content_charset;
60 if (source_charset == NULL)
61 source_charset = DEST_CHARSET;
62
63 r = charconv_buffer(source_charset, DEST_CHARSET,
64 data, len, &converted, &converted_len);
65 if (r != MAIL_CHARCONV_NO_ERROR) {
66
67 r = fprintf(f, "[ error converting charset from %s to %s ]\n",
68 source_charset, DEST_CHARSET);
69 if (r < 0) {
70 res = ERROR_FILE;
71 goto err;
72 }
73
74 write_len = fwrite(data, 1, len, f);
75 if (write_len != len) {
76 mailmime_decoded_part_free(data);
77 res = r;
78 goto err;
79 }
80 }
81 else {
82 write_len = fwrite(converted, 1, converted_len, f);
83 if (write_len != len) {
84 charconv_buffer_free(converted);
85 mailmime_decoded_part_free(data);
86 res = r;
87 goto err;
88 }
89
90 charconv_buffer_free(converted);
91 }
92
93 write_len = fwrite("\r\n\r\n", 1, 4, f);
94 if (write_len < 4) {
95 mailmime_decoded_part_free(data);
96 res = ERROR_FILE;
97 goto err;
98 }
99
100 mailmime_decoded_part_free(data);
101 }
102 else {
103 /* not viewable part */
104
105 r = fprintf(f, " (not shown)\n\n");
106 if (r < 0) {
107 res = ERROR_FILE;
108 goto err;
109 }
110 }
111
112 break;
113
114 case MAILMIME_MULTIPLE:
115
116 if (strcasecmp(mime->mm_content_type->ct_subtype, "alternative") == 0) {
117 struct mailmime * prefered_body;
118 int prefered_score;
119
120 /* case of multiple/alternative */
121
122 /*
123 we choose the better part,
124 alternative preference :
125
126 text/plain => score 3
127 text/xxx => score 2
128 other => score 1
129 */
130
131 prefered_body = NULL;
132 prefered_score = 0;
133
134 for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ;
135 cur != NULL ; cur = clist_next(cur)) {
136 struct mailmime * submime;
137 int score;
138
139 score = 1;
140 submime = clist_content(cur);
141 if (etpan_mime_is_text(submime))
142 score = 2;
143
144 if (submime->mm_content_type != NULL) {
145 if (strcasecmp(submime->mm_content_type->ct_subtype, "plain") == 0)
146 score = 3;
147 }
148
149 if (score > prefered_score) {
150 prefered_score = score;
151 prefered_body = submime;
152 }
153 }
154
155 if (prefered_body != NULL) {
156 r = etpan_render_mime(f, msg_info, prefered_body);
157 if (r != NO_ERROR) {
158 res = r;
159 goto err;
160 }
161 }
162 }
163 else {
164 for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ;
165 cur != NULL ; cur = clist_next(cur)) {
166
167 r = etpan_render_mime(f, msg_info, clist_content(cur));
168 if (r != NO_ERROR) {
169 res = r;
170 goto err;
171 }
172 }
173 }
174
175 break;
176
177 case MAILMIME_MESSAGE:
178
179 if (mime->mm_data.mm_message.mm_fields != NULL) {
180 struct mailimf_fields * fields;
181
182 if (msg_info != NULL) {
183 fields = fetch_fields(msg_info, mime);
184 if (fields == NULL) {
185 res = ERROR_FETCH;
186 goto err;
187 }
188
189 col = 0;
190 r = fields_write(f, &col, fields);
191 if (r != NO_ERROR) {
192 mailimf_fields_free(fields);
193 res = r;
194 goto err;
195 }
196
197 mailimf_fields_free(fields);
198 }
199 else {
200 col = 0;
201 r = fields_write(f, &col, mime->mm_data.mm_message.mm_fields);
202 if (r != NO_ERROR) {
203 res = r;
204 goto err;
205 }
206 }
207
208 r = fprintf(f, "\r\n");
209 if (r < 0) {
210 res = ERROR_FILE;
211 goto err;
212 }
213 }
214
215 if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
216 r = etpan_render_mime(f, msg_info, mime->mm_data.mm_message.mm_msg_mime);
217 if (r != NO_ERROR) {
218 res = r;
219 goto err;
220 }
221 }
222
223 break;
224 }
225
226 return NO_ERROR;
227
228 err:
229 return res;
230}
231
232
233int main(int argc, char ** argv)
234{
235 int r;
236 int driver;
237 char * server;
238 int port;
239 int connection_type;
240 char * user;
241 char * password;
242 int auth_type;
243 char * path;
244 char * cache_directory;
245 char * flags_directory;
246 struct mailstorage * storage;
247 int cached;
248 struct mailfolder * folder;
249
250 /* get options */
251
252 r = parse_options(argc, argv,
253 &driver, &server, &port, &connection_type,
254 &user, &password, &auth_type,
255 &path, &cache_directory, &flags_directory);
256
257 cached = (cache_directory != NULL);
258
259 /* build the storage structure */
260
261 storage = mailstorage_new(NULL);
262 if (storage == NULL) {
263 printf("error initializing storage\n");
264 goto free_opt;
265 }
266
267 r = init_storage(storage, driver, server, port, connection_type,
268 user, password, auth_type, path, cache_directory, flags_directory);
269 if (r != MAIL_NO_ERROR) {
270 printf("error initializing storage\n");
271 goto free_opt;
272 }
273
274 /* get the folder structure */
275
276 folder = mailfolder_new(storage, path, NULL);
277 if (folder == NULL) {
278 printf("error initializing folder\n");
279 goto free_storage;
280 }
281
282 r = mailfolder_connect(folder);
283 if (r != MAIL_NO_ERROR) {
284 printf("error initializing folder\n");
285 goto free_folder;
286 }
287
288 while (optind < argc) {
289 mailmessage * msg;
290 uint32_t msg_num;
291 struct mailmime * mime;
292
293 msg_num = strtoul(argv[optind], NULL, 10);
294
295 r = mailsession_get_message(folder->fld_session, msg_num, &msg);
296 if (r != MAIL_NO_ERROR) {
297 printf("** message %i not found ** - %s\n", msg_num,
298 maildriver_strerror(r));
299 optind ++;
300 continue;
301 }
302
303 r = mailmessage_get_bodystructure(msg, &mime);
304 if (r != MAIL_NO_ERROR) {
305 printf("** message %i not found - %s **\n", msg_num,
306 maildriver_strerror(r));
307 mailmessage_free(msg);
308 optind ++;
309 continue;
310 }
311
312 r = etpan_render_mime(stdout, msg, mime);
313
314 mailmessage_free(msg);
315
316 optind ++;
317 }
318
319 mailfolder_free(folder);
320 mailstorage_free(storage);
321
322 if (server != NULL)
323 free(server);
324 if (user != NULL)
325 free(user);
326 if (password != NULL)
327 free(password);
328 if (path != NULL)
329 free(path);
330 if (cache_directory != NULL)
331 free(cache_directory);
332 if (flags_directory != NULL)
333 free(flags_directory);
334
335 return 0;
336
337 free_folder:
338 mailfolder_free(folder);
339 free_storage:
340 mailstorage_free(storage);
341 free_opt:
342 if (server != NULL)
343 free(server);
344 if (user != NULL)
345 free(user);
346 if (password != NULL)
347 free(password);
348 if (path != NULL)
349 free(path);
350 if (cache_directory != NULL)
351 free(cache_directory);
352 if (flags_directory != NULL)
353 free(flags_directory);
354 return -1;
355}
diff --git a/kmicromail/libetpan/tests/smtpsend.c b/kmicromail/libetpan/tests/smtpsend.c
new file mode 100644
index 0000000..d5229d9
--- a/dev/null
+++ b/kmicromail/libetpan/tests/smtpsend.c
@@ -0,0 +1,278 @@
1/*
2 * Simple Mail Submission Agent using SMTP with libEtPan!
3 * TODO: Full sendmail like interface
4 */
5
6#include <libetpan/libetpan.h>
7#include <netdb.h>
8#include <netinet/in.h>
9#include <sys/socket.h>
10#include <stdlib.h>
11#include <string.h>
12#include <sys/types.h>
13#include <sys/mman.h>
14#include <sys/stat.h>
15#include <unistd.h>
16#include <sys/ioctl.h>
17#include <fcntl.h>
18#include <pwd.h>
19
20#define _GNU_SOURCE
21#include <getopt.h>
22
23/* globals */
24char *smtp_server;
25uint smtp_port = 25;
26char *smtp_user;
27char *smtp_password;
28char *smtp_from;
29int smtp_tls = 0;
30int smtp_esmtp = 1;
31
32struct mem_message {
33 char *data;
34 size_t len;
35 MMAPString *mstring;
36};
37
38#define BLOCKSIZE 4096
39
40int collect(struct mem_message *message) {
41 struct stat sb;
42 int len;
43
44 memset(message, 0, sizeof(struct mem_message));
45
46 /* if stdin is a file whose size is known, try to mmap it */
47 if (!fstat(0, &sb) && S_ISREG(sb.st_mode) && sb.st_size >= 0) {
48 message->len = sb.st_size;
49 if ((message->data = mmap(NULL, message->len, PROT_READ, MAP_SHARED,
50 STDIN_FILENO, 0)) != MAP_FAILED)
51 return 0;
52 }
53
54 /* read the buffer from stdin by blocks, until EOF or error.
55 save the message in a mmap_string */
56 if ((message->mstring = mmap_string_sized_new(BLOCKSIZE)) == NULL) {
57 perror("mmap_string_new");
58 goto error;
59 }
60 message->len = 0;
61
62 while ((len = read(STDIN_FILENO,
63 message->mstring->str + message->len, BLOCKSIZE)) > 0) {
64 message->len += len;
65 /* reserve room for next block */
66 if ((mmap_string_set_size(message->mstring,
67 message->len + BLOCKSIZE)) == NULL) {
68 perror("mmap_string_set_size");
69 goto error;
70 }
71 }
72
73 if (len == 0) {
74 message->data = message->mstring->str;
75 return 0; /* OK */
76 }
77
78 perror("read");
79
80 error:
81 if (message->mstring != NULL)
82 mmap_string_free(message->mstring);
83 return -1;
84}
85
86char *guessfrom() {
87 uid_t uid;
88 struct passwd *pw;
89 char hostname[256];
90 int len;
91 char *gfrom;
92
93 if (gethostname(hostname, sizeof(hostname))) {
94 perror("gethostname");
95 return NULL;
96 }
97 hostname[sizeof(hostname) - 1] = '\0';
98
99 uid = getuid();
100 pw = getpwuid(uid);
101
102 len = ((pw != NULL) ? strlen(pw->pw_name) : 12)
103 + strlen(hostname) + 2;
104
105 if ((gfrom = malloc(len)) == NULL) {
106 perror("malloc");
107 return NULL;
108 }
109 if (pw != NULL && pw->pw_name != NULL)
110 snprintf(gfrom, len, "%s@%s", pw->pw_name, hostname);
111 else
112 snprintf(gfrom, len, "#%u@%s", uid, hostname);
113 return gfrom;
114}
115
116void release(struct mem_message *message) {
117 if (message->mstring != NULL)
118 mmap_string_free(message->mstring);
119 else if (message->data != NULL)
120 munmap(message->data, message->len);
121}
122
123int send_message(char *data, size_t len, char**rcpts) {
124 int s = -1;
125 int ret;
126 char **r;
127 int esmtp = 0;
128 mailsmtp *smtp = NULL;
129
130 if ((smtp = mailsmtp_new(0, NULL)) == NULL) {
131 perror("mailsmtp_new");
132 goto error;
133 }
134
135 /* first open the stream */
136 if ((ret = mailsmtp_socket_connect(smtp,
137 (smtp_server != NULL ? smtp_server : "localhost"),
138 smtp_port)) != MAILSMTP_NO_ERROR) {
139 fprintf(stderr, "mailsmtp_socket_connect: %s\n", mailsmtp_strerror(ret));
140 goto error;
141 }
142
143 /* then introduce ourselves */
144 if (smtp_esmtp && (ret = mailesmtp_ehlo(smtp)) == MAILSMTP_NO_ERROR)
145 esmtp = 1;
146 else if (!smtp_esmtp || ret == MAILSMTP_ERROR_NOT_IMPLEMENTED)
147 ret = mailsmtp_helo(smtp);
148 if (ret != MAILSMTP_NO_ERROR) {
149 fprintf(stderr, "mailsmtp_helo: %s\n", mailsmtp_strerror(ret));
150 goto error;
151 }
152
153 if (esmtp && smtp_tls &&
154 (ret = mailsmtp_socket_starttls(smtp)) != MAILSMTP_NO_ERROR) {
155 fprintf(stderr, "mailsmtp_starttls: %s\n", mailsmtp_strerror(ret));
156 goto error;
157 }
158
159 if (esmtp && smtp_user != NULL &&
160 (ret = mailsmtp_auth(smtp, smtp_user,
161 (smtp_password != NULL) ? smtp_password : ""))
162 != MAILSMTP_NO_ERROR) {
163 fprintf(stderr, "mailsmtp_auth: %s: %s\n", smtp_user, mailsmtp_strerror(ret));
164 goto error;
165 }
166
167 /* source */
168 if ((ret = (esmtp ?
169 mailesmtp_mail(smtp, smtp_from, 1, "etPanSMTPTest") :
170 mailsmtp_mail(smtp, smtp_from))) != MAILSMTP_NO_ERROR) {
171 fprintf(stderr, "mailsmtp_mail: %s, %s\n", smtp_from, mailsmtp_strerror(ret));
172 goto error;
173 }
174
175 /* recipients */
176 for (r = rcpts; *r != NULL; r++) {
177 if ((ret = (esmtp ?
178 mailesmtp_rcpt(smtp, *r,
179 MAILSMTP_DSN_NOTIFY_FAILURE|MAILSMTP_DSN_NOTIFY_DELAY,
180 NULL) :
181 mailsmtp_rcpt(smtp, *r))) != MAILSMTP_NO_ERROR) {
182 fprintf(stderr, "mailsmtp_rcpt: %s: %s\n", *r, mailsmtp_strerror(ret));
183 goto error;
184 }
185 }
186
187 /* message */
188 if ((ret = mailsmtp_data(smtp)) != MAILSMTP_NO_ERROR) {
189 fprintf(stderr, "mailsmtp_data: %s\n", mailsmtp_strerror(ret));
190 goto error;
191 }
192 if ((ret = mailsmtp_data_message(smtp, data, len)) != MAILSMTP_NO_ERROR) {
193 fprintf(stderr, "mailsmtp_data_message: %s\n", mailsmtp_strerror(ret));
194 goto error;
195 }
196 mailsmtp_free(smtp);
197 return 0;
198
199 error:
200 if (smtp != NULL)
201 mailsmtp_free(smtp);
202 if (s >= 0)
203 close(s);
204 return -1;
205}
206
207int main(int argc, char **argv) {
208 struct mem_message message;
209 int index, r;
210
211 static struct option long_options[] = {
212 {"server", 1, 0, 's'},
213 {"port", 1, 0, 'p'},
214 {"user", 1, 0, 'u'},
215 {"password", 1, 0, 'v'},
216 {"from", 1, 0, 'f'},
217 {"tls", 0, 0, 'S'},
218 {"no-esmtp", 0, 0, 'E'},
219 };
220
221 while(1) {
222 if ((r = getopt_long(argc, argv, "s:p:u:v:f:SE", long_options, &index)) < 0)
223 break;
224 switch (r) {
225 case 's':
226 if (smtp_server != NULL)
227 free(smtp_server);
228 smtp_server = strdup(optarg);
229 break;
230 case 'p':
231 smtp_port = strtoul(optarg, NULL, 10);
232 break;
233 case 'u':
234 if (smtp_user != NULL)
235 free(smtp_user);
236 smtp_user = strdup(optarg);
237 break;
238 case 'v':
239 if (smtp_password != NULL)
240 free(smtp_password);
241 smtp_password = strdup(optarg);
242 break;
243 case 'f':
244 if (smtp_from != NULL)
245 free(smtp_from);
246 smtp_from = strdup(optarg);
247 break;
248 case 'S':
249 smtp_tls = 1;
250 break;
251 case 'E':
252 smtp_esmtp = 0;
253 break;
254 }
255 }
256
257 argc -= optind;
258 argv += optind;
259
260 if (argc < 1) {
261 fprintf(stderr, "usage: smtpsend [-f from] [-u user] [-v password] [-s server] [-p port] [-S] <rcpts>...\n");
262 return EXIT_FAILURE;
263 }
264
265 if (smtp_from == NULL && (smtp_from = guessfrom()) == NULL) {
266 fprintf(stderr, "can't guess a valid from, please use -f option.\n");
267 return EXIT_FAILURE;
268 }
269
270 /* reads message from stdin */
271 if (collect(&message))
272 return EXIT_FAILURE;
273
274 send_message(message.data, message.len, argv);
275
276 release(&message);
277 return EXIT_SUCCESS;
278}
diff --git a/kmicromail/libetpan/tools/.libs/libtools.a b/kmicromail/libetpan/tools/.libs/libtools.a
new file mode 100644
index 0000000..43424ef
--- a/dev/null
+++ b/kmicromail/libetpan/tools/.libs/libtools.a
Binary files differ
diff --git a/kmicromail/libetpan/tools/base64.c b/kmicromail/libetpan/tools/base64.c
new file mode 100644
index 0000000..1532bac
--- a/dev/null
+++ b/kmicromail/libetpan/tools/base64.c
@@ -0,0 +1,143 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - Juergen Graf
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "base64.h"
37
38#include <stdlib.h>
39
40#define OUTPUT_SIZE 513
41#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
42
43static char index_64[128] = {
44 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
45 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
46 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
47 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
48 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
49 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
50 -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
51 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
52};
53
54static char basis_64[] =
55 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
56
57char * encode_base64(const char * in, int len)
58{
59 char * output, * tmp;
60 unsigned char oval;
61 int out_len;
62
63 out_len = ((len + 2) / 3 * 4) + 1;
64
65 if ((len > 0) && (in == NULL))
66 return NULL;
67
68 output = malloc(out_len);
69 if (!output)
70 return NULL;
71
72 tmp = output;
73 while (len >= 3) {
74 *tmp++ = basis_64[in[0] >> 2];
75 *tmp++ = basis_64[((in[0] << 4) & 0x30) | (in[1] >> 4)];
76 *tmp++ = basis_64[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
77 *tmp++ = basis_64[in[2] & 0x3f];
78 in += 3;
79 len -= 3;
80 }
81 if (len > 0) {
82 *tmp++ = basis_64[in[0] >> 2];
83 oval = (in[0] << 4) & 0x30;
84 if (len > 1) oval |= in[1] >> 4;
85 *tmp++ = basis_64[oval];
86 *tmp++ = (len < 2) ? '=' : basis_64[(in[1] << 2) & 0x3c];
87 *tmp++ = '=';
88 }
89
90 *tmp = '\0';
91
92 return output;
93}
94
95char * decode_base64(const char * in, int len)
96{
97 char * output, * out;
98 int i, c1, c2, c3, c4, out_len;
99
100 out_len = 0;
101
102 output = malloc(OUTPUT_SIZE);
103 if (output == NULL)
104 return NULL;
105 out = output;
106
107 if (in[0] == '+' && in[1] == ' ')
108 in += 2;
109
110 for (i = 0; i < (len / 4); i++) {
111 c1 = in[0];
112 c2 = in[1];
113 c3 = in[2];
114 c4 = in[3];
115 if (CHAR64(c1) == -1 || CHAR64(c2) == -1 ||
116 (c3 != '=' && CHAR64(c3) == -1) ||
117 (c4 != '=' && CHAR64(c4) == -1))
118 return NULL;
119
120 in += 4;
121 *output++ = (CHAR64(c1) << 2) | (CHAR64(c2) >> 4);
122 if (++out_len >= OUTPUT_SIZE)
123 return NULL;
124
125 if (c3 != '=') {
126 *output++ = ((CHAR64(c2) << 4) & 0xf0) | (CHAR64(c3) >> 2);
127 if (++out_len >= OUTPUT_SIZE)
128 return NULL;
129
130 if (c4 != '=') {
131 *output++ = ((CHAR64(c3) << 6) & 0xc0) | CHAR64(c4);
132 if (++out_len >= OUTPUT_SIZE)
133 return NULL;
134 }
135 }
136 }
137
138 *output = 0;
139
140 return out;
141}
142
143
diff --git a/kmicromail/libetpan/tools/base64.h b/kmicromail/libetpan/tools/base64.h
new file mode 100644
index 0000000..aa5f3e5
--- a/dev/null
+++ b/kmicromail/libetpan/tools/base64.h
@@ -0,0 +1,59 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - Juergen Graf
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef BASE64_H
37#define BASE64_H
38
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43/**
44 * creates (malloc) a new base64 encoded string from a standard 8bit string
45 * don't forget to free it when time comes ;)
46 */
47char * encode_base64(const char * in, int len);
48
49/**
50 * creates (malloc) a new standard 8bit string from an base64 encoded string
51 * don't forget to free it when time comes ;)
52 */
53char * decode_base64(const char * in, int len);
54
55#ifdef __cplusplus
56}
57#endif
58
59#endif
diff --git a/kmicromail/libetpan/tools/carray.c b/kmicromail/libetpan/tools/carray.c
new file mode 100644
index 0000000..a8e78c9
--- a/dev/null
+++ b/kmicromail/libetpan/tools/carray.c
@@ -0,0 +1,143 @@
1
2/*
3 * libEtPan! -- a mail stuff library
4 *
5 * carray - Implements simple dynamic pointer arrays
6 *
7 * Copyright (c) 1999-2000, Gaël Roualland <gael.roualland@iname.com>
8 * interface changes - 2002 - DINH Viet Hoa
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the libEtPan! project nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36/*
37 * $Id$
38 */
39
40#include <stdlib.h>
41#include <string.h>
42#include "carray.h"
43
44carray * carray_new(unsigned int initsize) {
45 carray * array;
46
47 array = (carray *) malloc(sizeof(carray));
48 if (!array) return NULL;
49
50 array->len = 0;
51 array->max = initsize;
52 array->array = (void **) malloc(sizeof(void *) * initsize);
53 if (!array->array) {
54 free(array);
55 return NULL;
56 }
57 return array;
58}
59
60int carray_add(carray * array, void * data, unsigned int * index) {
61 int r;
62
63 r = carray_set_size(array, array->len + 1);
64 if (r < 0)
65 return r;
66
67 array->array[array->len - 1] = data;
68 if (index != NULL)
69 * index = array->len - 1;
70
71 return 0;
72}
73
74int carray_set_size(carray * array, unsigned int new_size)
75{
76 if (new_size > array->max) {
77 unsigned int n = array->max * 2;
78 void * new;
79
80 while (n <= new_size)
81 n *= 2;
82
83 new = (void **) realloc(array->array, sizeof(void *) * n);
84 if (!new)
85 return -1;
86 array->array = new;
87 array->max = n;
88 }
89 array->len = new_size;
90
91 return 0;
92}
93
94int carray_delete_fast(carray * array, unsigned int indx) {
95 if (indx >= array->len)
96 return -1;
97
98 array->array[indx] = NULL;
99
100 return 0;
101}
102
103int carray_delete(carray * array, unsigned int indx) {
104 if (indx >= array->len)
105 return -1;
106
107 if (indx != --array->len)
108 array->array[indx] = array->array[array->len];
109 return 0;
110}
111
112int carray_delete_slow(carray * array, unsigned int indx) {
113 if (indx >= array->len)
114 return -1;
115
116 if (indx != --array->len)
117 memmove(array->array + indx, array->array + indx + 1,
118 (array->len - indx) * sizeof(void *));
119 return 0;
120}
121
122#ifdef NO_MACROS
123void ** carray_data(carray * array) {
124 return array->array;
125}
126
127unsigned int carray_count(carray * array) {
128 return array->len;
129}
130
131void * carray_get(carray * array, unsigned int indx) {
132 return array->array[indx];
133}
134
135void carray_set(carray * array, unsigned int indx, void * value) {
136 array->array[indx] = value;
137}
138#endif
139
140void carray_free(carray * array) {
141 free(array->array);
142 free(array);
143}
diff --git a/kmicromail/libetpan/tools/carray.h b/kmicromail/libetpan/tools/carray.h
new file mode 100644
index 0000000..06003aa
--- a/dev/null
+++ b/kmicromail/libetpan/tools/carray.h
@@ -0,0 +1,124 @@
1
2/*
3 * libEtPan! -- a mail stuff library
4 *
5 * carray - Implements simple dynamic pointer arrays
6 *
7 * Copyright (c) 1999-2000, Gaël Roualland <gael.roualland@iname.com>
8 * interface changes - 2002 - DINH Viet Hoa
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the libEtPan! project nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36/*
37 * $Id$
38 */
39
40#ifndef CARRAY_H
41#define CARRAY_H
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47struct carray_s {
48 void ** array;
49 unsigned int len;
50 unsigned int max;
51};
52
53typedef struct carray_s carray;
54
55/* Creates a new array of pointers, with initsize preallocated cells */
56carray * carray_new(unsigned int initsize);
57
58/* Adds the pointer to data in the array.
59 Returns the index of the pointer in the array or -1 on error */
60int carray_add(carray * array, void * data, unsigned int * index);
61
62int carray_set_size(carray * array, unsigned int new_size);
63
64/* Removes the cell at this index position. Returns TRUE on success.
65 Order of elements in the array IS changed. */
66int carray_delete(carray * array, unsigned int indx);
67
68/* Removes the cell at this index position. Returns TRUE on success.
69 Order of elements in the array IS not changed. */
70int carray_delete_slow(carray * array, unsigned int indx);
71
72/* remove without decreasing the size of the array */
73int carray_delete_fast(carray * array, unsigned int indx);
74
75/* Some of the following routines can be implemented as macros to
76 be faster. If you don't want it, define NO_MACROS */
77#ifdef NO_MACROS
78
79/* Returns the array itself */
80void ** carray_data(carray *);
81
82/* Returns the number of elements in the array */
83int carray_count(carray *);
84
85/* Returns the contents of one cell */
86void * carray_get(carray * array, unsigned int indx);
87
88/* Sets the contents of one cell */
89void carray_set(carray * array, unsigned int indx, void * value);
90
91#else
92
93#if 0
94#define carray_data(a) (a->array)
95#define carray_count(a) (a->len)
96#define carray_get(a, indx) (a->array[indx])
97#define carray_set(a, indx, v) do { a->array[indx]=v; } while(0)
98#endif
99
100static inline void ** carray_data(carray * array) {
101 return array->array;
102}
103
104static inline unsigned int carray_count(carray * array) {
105 return array->len;
106}
107
108static inline void * carray_get(carray * array, unsigned int indx) {
109 return array->array[indx];
110}
111
112static inline void carray_set(carray * array,
113 unsigned int indx, void * value) {
114 array->array[indx] = value;
115}
116#endif
117
118void carray_free(carray * array);
119
120#ifdef __cplusplus
121}
122#endif
123
124#endif
diff --git a/kmicromail/libetpan/tools/charconv.c b/kmicromail/libetpan/tools/charconv.c
new file mode 100644
index 0000000..bf3de51
--- a/dev/null
+++ b/kmicromail/libetpan/tools/charconv.c
@@ -0,0 +1,251 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "charconv.h"
37
38#include "config.h"
39#ifdef HAVE_ICONV
40#include <iconv.h>
41#endif
42#include <stdlib.h>
43#include <string.h>
44#include <stdio.h>
45#include <errno.h>
46
47#include "mmapstring.h"
48
49#ifdef HAVE_ICONV
50static size_t mail_iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft,
51 char **outbuf, size_t *outbytesleft,
52 char **inrepls, char *outrepl)
53{
54 /*
55 XXX - force conversion of (* inbuf) to (char *)
56 because prototype of iconv() is the following :
57
58 size_t iconv(iconv_t cd, char **restrict inbuf,
59 size_t *restrict inbytesleft, char **restrict outbuf,
60 size_t *restrict outbytesleft);
61 */
62
63 size_t ret = 0, ret1;
64 char *ib = (char *) *inbuf;
65 size_t ibl = *inbytesleft;
66 char *ob = *outbuf;
67 size_t obl = *outbytesleft;
68
69 for (;;)
70 {
71 ret1 = iconv (cd, &ib, &ibl, &ob, &obl);
72 if (ret1 != (size_t)-1)
73 ret += ret1;
74 if (ibl && obl && errno == EILSEQ)
75 {
76 if (inrepls)
77 {
78 /* Try replacing the input */
79 char **t;
80 for (t = inrepls; *t; t++)
81 {
82 char *ib1 = *t;
83 size_t ibl1 = strlen (*t);
84 char *ob1 = ob;
85 size_t obl1 = obl;
86 iconv (cd, &ib1, &ibl1, &ob1, &obl1);
87 if (!ibl1)
88 {
89 ++ib, --ibl;
90 ob = ob1, obl = obl1;
91 ++ret;
92 break;
93 }
94 }
95 if (*t)
96 continue;
97 }
98 if (outrepl)
99 {
100 /* Try replacing the output */
101 size_t n = strlen (outrepl);
102 if (n <= obl)
103 {
104 memcpy (ob, outrepl, n);
105 ++ib, --ibl;
106 ob += n, obl -= n;
107 ++ret;
108 continue;
109 }
110 }
111 }
112 *inbuf = ib, *inbytesleft = ibl;
113 *outbuf = ob, *outbytesleft = obl;
114 return ret;
115 }
116}
117#endif
118
119int charconv(const char * tocode, const char * fromcode,
120 const char * str, size_t length,
121 char ** result)
122{
123#ifndef HAVE_ICONV
124 return MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET;
125#else
126 iconv_t conv;
127 size_t r;
128 char * out;
129 char * pout;
130 size_t out_size;
131 size_t old_out_size;
132 size_t count;
133 int res;
134
135 conv = iconv_open(tocode, fromcode);
136 if (conv == (iconv_t) -1) {
137 res = MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET;
138 goto err;
139 }
140
141 out_size = 4 * length;
142
143 out = malloc(out_size + 1);
144 if (out == NULL) {
145 res = MAIL_CHARCONV_ERROR_MEMORY;
146 goto close_iconv;
147 }
148
149 pout = out;
150 old_out_size = out_size;
151
152 r = mail_iconv(conv, &str, &length, &pout, &out_size, NULL, "?");
153
154 if (r == (size_t) -1) {
155 res = MAIL_CHARCONV_ERROR_CONV;
156 goto free;
157 }
158
159 iconv_close(conv);
160
161 * pout = '\0';
162 count = old_out_size - out_size;
163 pout = realloc(out, count + 1);
164 if (pout != NULL)
165 out = pout;
166
167 * result = out;
168
169 return MAIL_CHARCONV_NO_ERROR;
170
171 free:
172 free(out);
173 close_iconv:
174 iconv_close(conv);
175 err:
176 return res;
177#endif
178};
179
180int charconv_buffer(const char * tocode, const char * fromcode,
181 const char * str, size_t length,
182 char ** result, size_t * result_len)
183{
184#ifndef HAVE_ICONV
185 return MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET;
186#else
187 iconv_t conv;
188 size_t iconv_r;
189 int r;
190 char * out;
191 char * pout;
192 size_t out_size;
193 size_t old_out_size;
194 size_t count;
195 MMAPString * mmapstr;
196 int res;
197
198 conv = iconv_open(tocode, fromcode);
199 if (conv == (iconv_t) -1) {
200 res = MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET;
201 goto err;
202 }
203
204 out_size = 4 * length;
205
206 mmapstr = mmap_string_sized_new(out_size + 1);
207 if (mmapstr == NULL) {
208 res = MAIL_CHARCONV_ERROR_MEMORY;
209 goto err;
210 }
211
212 out = mmapstr->str;
213
214 pout = out;
215 old_out_size = out_size;
216
217 iconv_r = mail_iconv(conv, &str, &length, &pout, &out_size, NULL, "?");
218
219 if (iconv_r == (size_t) -1) {
220 res = MAIL_CHARCONV_ERROR_CONV;
221 goto free;
222 }
223
224 iconv_close(conv);
225
226 * pout = '\0';
227
228 count = old_out_size - out_size;
229
230 r = mmap_string_ref(mmapstr);
231 if (r < 0) {
232 res = MAIL_CHARCONV_ERROR_MEMORY;
233 goto free;
234 }
235
236 * result = out;
237 * result_len = count;
238
239 return MAIL_CHARCONV_NO_ERROR;
240
241 free:
242 mmap_string_free(mmapstr);
243 err:
244 return -1;
245#endif
246};
247
248void charconv_buffer_free(char * str)
249{
250 mmap_string_unref(str);
251}
diff --git a/kmicromail/libetpan/tools/charconv.h b/kmicromail/libetpan/tools/charconv.h
new file mode 100644
index 0000000..5a435ff
--- a/dev/null
+++ b/kmicromail/libetpan/tools/charconv.h
@@ -0,0 +1,67 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef CHARCONV_H
37
38#define CHARCONV_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <sys/types.h>
45
46enum {
47 MAIL_CHARCONV_NO_ERROR = 0,
48 MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET,
49 MAIL_CHARCONV_ERROR_MEMORY,
50 MAIL_CHARCONV_ERROR_CONV,
51};
52
53int charconv(const char * tocode, const char * fromcode,
54 const char * str, size_t length,
55 char ** result);
56
57int charconv_buffer(const char * tocode, const char * fromcode,
58 const char * str, size_t length,
59 char ** result, size_t * result_len);
60
61void charconv_buffer_free(char * str);
62
63#ifdef __cplusplus
64}
65#endif
66
67#endif
diff --git a/kmicromail/libetpan/tools/chash.c b/kmicromail/libetpan/tools/chash.c
new file mode 100644
index 0000000..2055221
--- a/dev/null
+++ b/kmicromail/libetpan/tools/chash.c
@@ -0,0 +1,395 @@
1
2/*
3 * libEtPan! -- a mail stuff library
4 *
5 * chash - Implements generic hash tables.
6 *
7 * Copyright (c) 1999-2000, Gaël Roualland <gael.roualland@iname.com>
8 * interface changes - 2002 - DINH Viet Hoa
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the libEtPan! project nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36/*
37 * $Id$
38 */
39
40#include <stdlib.h>
41#include <string.h>
42
43#include "chash.h"
44
45/* This defines the maximum (average) number of entries per bucket.
46 The hash is resized everytime inserting an entry makes the
47 average go over that value. */
48#define CHASH_MAXDEPTH 3
49
50static inline unsigned int chash_func(const char * key, unsigned int len) {
51#if 0
52 register unsigned int c = 0, t;
53 register const char * k = key;
54
55 while (len--) {
56 c += (c << 4) + *k++;
57 if ((t = c & 0xF0000000)) {
58 c ^= t >> 24;
59 c ^= t;
60 }
61 }
62 return c;
63#endif
64 register unsigned int c = 5381;
65 register const char * k = key;
66
67 while (len--) {
68 c = ((c << 5) + c) + *k++;
69 }
70
71 return c;
72}
73
74static inline char * chash_dup(const void * data, unsigned int len)
75{
76 void * r;
77
78 r = (char *) malloc(len);
79 if (!r)
80 return NULL;
81 memcpy(r, data, len);
82 return r;
83}
84
85chash * chash_new(unsigned int size, int flags)
86{
87 chash * h;
88
89 h = (chash *) malloc(sizeof(chash));
90 if (h == NULL)
91 return NULL;
92
93 h->count = 0;
94 h->cells = (struct chashcell **) calloc(size, sizeof(struct chashcell *));
95 if (h->cells == NULL) {
96 free(h);
97 return NULL;
98 }
99 h->size = size;
100 h->copykey = flags & CHASH_COPYKEY;
101 h->copyvalue = flags & CHASH_COPYVALUE;
102
103 return h;
104}
105
106int chash_get(chash * hash,
107 chashdatum * key, chashdatum * result)
108{
109 unsigned int func;
110 chashiter * iter;
111
112 func = chash_func(key->data, key->len);
113
114 /* look for the key in existing cells */
115 iter = hash->cells[func % hash->size];
116 while (iter) {
117 if (iter->key.len == key->len && iter->func == func
118 && !memcmp(iter->key.data, key->data, key->len)) {
119 * result = iter->value; /* found */
120
121 return 0;
122 }
123 iter = iter->next;
124 }
125
126 return -1;
127}
128
129int chash_set(chash * hash,
130 chashdatum * key,
131 chashdatum * value,
132 chashdatum * oldvalue)
133{
134 unsigned int func, indx;
135 chashiter * iter, * cell;
136 int r;
137
138 if (hash->count > hash->size * CHASH_MAXDEPTH) {
139 r = chash_resize(hash, (hash->count / CHASH_MAXDEPTH) * 2 + 1);
140 if (r < 0)
141 goto err;
142 }
143
144 func = chash_func(key->data, key->len);
145 indx = func % hash->size;
146
147 /* look for the key in existing cells */
148 iter = hash->cells[indx];
149 while (iter) {
150 if (iter->key.len == key->len && iter->func == func
151 && !memcmp(iter->key.data, key->data, key->len)) {
152 /* found, replacing entry */
153 if (hash->copyvalue) {
154 char * data;
155
156 data = chash_dup(value->data, value->len);
157 if (data == NULL)
158 goto err;
159
160 free(iter->value.data);
161 iter->value.data = data;
162 iter->value.len = value->len;
163 } else {
164 if (oldvalue != NULL) {
165 oldvalue->data = iter->value.data;
166 oldvalue->len = iter->value.len;
167 }
168 iter->value.data = value->data;
169 iter->value.len = value->len;
170 }
171 if (!hash->copykey)
172 iter->key.data = key->data;
173
174 if (oldvalue != NULL) {
175 oldvalue->data = value->data;
176 oldvalue->len = value->len;
177 }
178
179 return 0;
180 }
181 iter = iter->next;
182 }
183
184 if (oldvalue != NULL) {
185 oldvalue->data = NULL;
186 oldvalue->len = 0;
187 }
188
189 /* not found, adding entry */
190 cell = (struct chashcell *) malloc(sizeof(struct chashcell));
191 if (cell == NULL)
192 goto err;
193
194 if (hash->copykey) {
195 cell->key.data = chash_dup(key->data, key->len);
196 if (cell->key.data == NULL)
197 goto free;
198 }
199 else
200 cell->key.data = key->data;
201
202 cell->key.len = key->len;
203 if (hash->copyvalue) {
204 cell->value.data = chash_dup(value->data, value->len);
205 if (cell->value.data == NULL)
206 goto free_key_data;
207 }
208 else
209 cell->value.data = value->data;
210
211 cell->value.len = value->len;
212 cell->func = func;
213 cell->next = hash->cells[indx];
214 hash->cells[indx] = cell;
215 hash->count++;
216
217 return 0;
218
219 free_key_data:
220 if (hash->copykey)
221 free(cell->key.data);
222 free:
223 free(cell);
224 err:
225 return -1;
226}
227
228int chash_delete(chash * hash, chashdatum * key, chashdatum * oldvalue)
229{
230 /* chashdatum result = { NULL, TRUE }; */
231 unsigned int func, indx;
232 chashiter * iter, * old;
233
234 /*
235 if (!keylen)
236 keylen = strlen(key) + 1;
237 */
238
239 func = chash_func(key->data, key->len);
240 indx = func % hash->size;
241
242 /* look for the key in existing cells */
243 old = NULL;
244 iter = hash->cells[indx];
245 while (iter) {
246 if (iter->key.len == key->len && iter->func == func
247 && !memcmp(iter->key.data, key->data, key->len)) {
248 /* found, deleting */
249 if (old)
250 old->next = iter->next;
251 else
252 hash->cells[indx] = iter->next;
253 if (hash->copykey)
254 free(iter->key.data);
255 if (hash->copyvalue)
256 free(iter->value.data);
257 else {
258 if (oldvalue != NULL) {
259 oldvalue->data = iter->value.data;
260 oldvalue->len = iter->value.len;
261 }
262 }
263 free(iter);
264 hash->count--;
265 return 0;
266 }
267 old = iter;
268 iter = iter->next;
269 }
270
271 return -1; /* not found */
272}
273
274void chash_free(chash * hash) {
275 unsigned int indx;
276 chashiter * iter, * next;
277
278 /* browse the hash table */
279 for(indx = 0; indx < hash->size; indx++) {
280 iter = hash->cells[indx];
281 while (iter) {
282 next = iter->next;
283 if (hash->copykey)
284 free(iter->key.data);
285 if (hash->copyvalue)
286 free(iter->value.data);
287 free(iter);
288 iter = next;
289 }
290 }
291 free(hash->cells);
292 free(hash);
293}
294
295void chash_clear(chash * hash) {
296 unsigned int indx;
297 chashiter * iter, * next;
298
299 /* browse the hash table */
300 for(indx = 0; indx < hash->size; indx++) {
301 iter = hash->cells[indx];
302 while (iter) {
303 next = iter->next;
304 if (hash->copykey)
305 free(iter->key.data);
306 if (hash->copyvalue)
307 free(iter->value.data);
308 free(iter);
309 iter = next;
310 }
311 }
312 memset(hash->cells, 0, hash->size * sizeof(* hash->cells));
313 hash->count = 0;
314}
315
316chashiter * chash_begin(chash * hash) {
317 chashiter * iter;
318 unsigned int indx = 0;
319
320 iter = hash->cells[0];
321 while(!iter) {
322 indx++;
323 if (indx >= hash->size)
324 return NULL;
325 iter = hash->cells[indx];
326 }
327 return iter;
328}
329
330chashiter * chash_next(chash * hash, chashiter * iter) {
331 unsigned int indx;
332
333 if (!iter)
334 return NULL;
335
336 indx = iter->func % hash->size;
337 iter = iter->next;
338
339 while(!iter) {
340 indx++;
341 if (indx >= hash->size)
342 return NULL;
343 iter = hash->cells[indx];
344 }
345 return iter;
346}
347
348int chash_resize(chash * hash, unsigned int size)
349{
350 struct chashcell ** cells;
351 unsigned int indx, nindx;
352 chashiter * iter, * next;
353
354 if (hash->size == size)
355 return 0;
356
357 cells = (struct chashcell **) calloc(size, sizeof(struct chashcell *));
358 if (!cells)
359 return -1;
360
361 /* browse initial hash and copy items in second hash */
362 for(indx = 0; indx < hash->size; indx++) {
363 iter = hash->cells[indx];
364 while (iter) {
365 next = iter->next;
366 nindx = iter->func % size;
367 iter->next = cells[nindx];
368 cells[nindx] = iter;
369 iter = next;
370 }
371 }
372 free(hash->cells);
373 hash->size = size;
374 hash->cells = cells;
375
376 return 0;
377}
378
379#ifdef NO_MACROS
380int chash_count(chash * hash) {
381 return hash->count;
382}
383
384int chash_size(chash * hash) {
385 return hash->size;
386}
387
388void chash_value(chashiter * iter, chashdatum * result) {
389 * result = iter->value;
390}
391
392void chash_key(chashiter * iter, chashdatum * result) {
393 * result = iter->key;
394}
395#endif
diff --git a/kmicromail/libetpan/tools/chash.h b/kmicromail/libetpan/tools/chash.h
new file mode 100644
index 0000000..3b2b7d3
--- a/dev/null
+++ b/kmicromail/libetpan/tools/chash.h
@@ -0,0 +1,166 @@
1
2/*
3 * libEtPan! -- a mail stuff library
4 *
5 * chash - Implements generic hash tables.
6 *
7 * Copyright (c) 1999-2000, Gaël Roualland <gael.roualland@iname.com>
8 * interface changes - 2002 - DINH Viet Hoa
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the libEtPan! project nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36/*
37 * $Id$
38 */
39
40#ifndef CHASH_H
41#define CHASH_H
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47typedef struct {
48 void * data;
49 unsigned int len;
50} chashdatum;
51
52struct chash {
53 unsigned int size;
54 unsigned int count;
55 int copyvalue;
56 int copykey;
57 struct chashcell ** cells;
58};
59
60typedef struct chash chash;
61
62struct chashcell {
63 unsigned int func;
64 chashdatum key;
65 chashdatum value;
66 struct chashcell * next;
67};
68
69typedef struct chashcell chashiter;
70
71#define CHASH_COPYNONE 0
72#define CHASH_COPYKEY 1
73#define CHASH_COPYVALUE 2
74#define CHASH_COPYALL (CHASH_COPYKEY | CHASH_COPYVALUE)
75
76#define CHASH_DEFAULTSIZE 13
77
78/* Allocates a new (empty) hash using this initial size and the given flags,
79 specifying which data should be copied in the hash.
80 CHASH_COPYNONE : Keys/Values are not copied.
81 CHASH_COPYKEY : Keys are dupped and freed as needed in the hash.
82 CHASH_COPYVALUE : Values are dupped and freed as needed in the hash.
83 CHASH_COPYALL : Both keys and values are dupped in the hash.
84 */
85chash * chash_new(unsigned int size, int flags);
86
87/* Frees a hash */
88void chash_free(chash * hash);
89
90/* Removes all elements from a hash */
91void chash_clear(chash * hash);
92
93/* Adds an entry in the hash table.
94 Length can be 0 if key/value are strings.
95 If an entry already exists for this key, it is replaced, and its value
96 is returned. Otherwise, the data pointer will be NULL and the length
97 field be set to TRUE or FALSe to indicate success or failure. */
98int chash_set(chash * hash,
99 chashdatum * key,
100 chashdatum * value,
101 chashdatum * oldvalue);
102
103/* Retrieves the data associated to the key if it is found in the hash table.
104 The data pointer and the length will be NULL if not found*/
105int chash_get(chash * hash,
106 chashdatum * key, chashdatum * result);
107
108/* Removes the entry associated to this key if it is found in the hash table,
109 and returns its contents if not dupped (otherwise, pointer will be NULL
110 and len TRUE). If entry is not found both pointer and len will be NULL. */
111int chash_delete(chash * hash,
112 chashdatum * key,
113 chashdatum * oldvalue);
114
115/* Resizes the hash table to the passed size. */
116int chash_resize(chash * hash, unsigned int size);
117
118/* Returns an iterator to the first non-empty entry of the hash table */
119chashiter * chash_begin(chash * hash);
120
121/* Returns the next non-empty entry of the hash table */
122chashiter * chash_next(chash * hash, chashiter * iter);
123
124/* Some of the following routines can be implemented as macros to
125 be faster. If you don't want it, define NO_MACROS */
126#ifdef NO_MACROS
127/* Returns the size of the hash table */
128unsigned int chash_size(chash * hash);
129
130/* Returns the number of entries in the hash table */
131unsigned int chash_count(chash * hash);
132
133/* Returns the key part of the entry pointed by the iterator */
134void chash_key(chashiter * iter, chashdatum * result);
135
136/* Returns the value part of the entry pointed by the iterator */
137void chash_value(chashiter * iter, chashdatum * result);
138
139#else
140static inline unsigned int chash_size(chash * hash)
141{
142 return hash->size;
143}
144
145static inline unsigned int chash_count(chash * hash)
146{
147 return hash->count;
148}
149
150static inline void chash_key(chashiter * iter, chashdatum * result)
151{
152 * result = iter->key;
153}
154
155static inline void chash_value(chashiter * iter, chashdatum * result)
156{
157 * result = iter->value;
158}
159
160#endif
161
162#ifdef __cplusplus
163}
164#endif
165
166#endif
diff --git a/kmicromail/libetpan/tools/cinthash.c b/kmicromail/libetpan/tools/cinthash.c
new file mode 100644
index 0000000..02ee727
--- a/dev/null
+++ b/kmicromail/libetpan/tools/cinthash.c
@@ -0,0 +1,248 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include <stdlib.h>
37#include "cinthash.h"
38
39struct cinthash_list {
40 unsigned long hash;
41 void * data;
42 struct cinthash_list * next;
43};
44
45static struct cinthash_list HASH_LISTHEAD_NEW = { 0, NULL, NULL };
46
47static inline int hash_list_add(cinthash_t * table,
48 unsigned long hash, void * data)
49{
50 struct cinthash_list * ht;
51 int index;
52
53 index = hash % table->hashtable_size;
54
55 ht = malloc(sizeof(struct cinthash_list));
56 if (ht == NULL)
57 return -1;
58
59 ht->hash = hash;
60 ht->data = data;
61 ht->next = table->table[index].next;
62
63 table->table[index].next = ht;
64
65 return 0;
66}
67
68static inline void hash_list_free(struct cinthash_list * list)
69{
70 struct cinthash_list * cur;
71 struct cinthash_list * next;
72
73 next = list;
74 while (next != NULL) {
75 cur = next;
76 next = cur->next;
77 free(cur);
78 }
79}
80
81static inline int hash_list_remove(cinthash_t * table, unsigned long hash)
82{
83 struct cinthash_list * cur;
84 int index;
85
86 index = hash % table->hashtable_size;
87
88 for(cur = &table->table[index] ; cur->next != NULL ; cur = cur->next) {
89 if (cur->next->hash == hash) {
90 struct cinthash_list * hash_data;
91
92 hash_data = cur->next;
93 cur->next = cur->next->next;
94
95 free(hash_data);
96
97 return 0;
98 }
99 }
100
101 return -1;
102}
103
104static inline void * hash_list_find(cinthash_t * table, unsigned long hash)
105{
106 struct cinthash_list * cur;
107 int index;
108
109 index = hash % table->hashtable_size;
110
111 for(cur = table->table[index].next ; cur != NULL ; cur = cur->next) {
112 if (cur->hash == hash)
113 return cur->data;
114 }
115
116 return NULL;
117}
118
119cinthash_t * cinthash_new(unsigned long hashtable_size)
120{
121 cinthash_t * ht;
122 unsigned long i;
123
124 ht = malloc(sizeof(cinthash_t));
125 if (ht == NULL)
126 return NULL;
127
128 ht->table = malloc(sizeof(struct cinthash_list) * hashtable_size);
129 if (ht->table == NULL)
130 return NULL;
131
132 ht->hashtable_size = hashtable_size;
133 ht->count = 0;
134
135 for(i = 0 ; i < hashtable_size ; i++)
136 ht->table[i] = HASH_LISTHEAD_NEW;
137
138 return ht;
139}
140
141void cinthash_free(cinthash_t * table)
142{
143 unsigned long i;
144
145 for(i = 0 ; i < table->hashtable_size ; i++)
146 hash_list_free(table->table[i].next);
147
148 free(table->table);
149
150 free(table);
151}
152
153int cinthash_add(cinthash_t * table, unsigned long hash, void * data)
154{
155 int index;
156
157 index = hash % table->hashtable_size;
158
159 if (table->table[index].data == NULL) {
160 table->table[index].hash = hash;
161 table->table[index].data = data;
162 table->table[index].next = NULL;
163
164 table->count ++;
165
166 return 0;
167 }
168 else {
169 int r;
170
171 r = hash_list_add(table, hash, data);
172 if (r == -1)
173 return -1;
174
175 table->count ++;
176
177 return 0;
178 }
179}
180
181int cinthash_remove(cinthash_t * table, unsigned long hash)
182{
183 int index;
184
185 index = hash % table->hashtable_size;
186
187 if (table->table[index].hash == hash) {
188 table->table[index].hash = 0;
189 table->table[index].data = NULL;
190
191 table->count --;
192
193 return 0;
194 }
195 else {
196 int r;
197
198 r = hash_list_remove(table, hash);
199
200 table->count --;
201
202 return 0;
203 }
204}
205
206void * cinthash_find(cinthash_t * table, unsigned long hash)
207{
208 int index;
209
210 index = hash % table->hashtable_size;
211
212 if (table->table[index].hash == hash)
213 return table->table[index].data;
214
215 return hash_list_find(table, hash);
216}
217
218void cinthash_foreach_key(cinthash_t * table,
219 void (* func)(unsigned long, void *),
220 void * data)
221{
222 unsigned long index;
223 struct cinthash_list * cur;
224
225 for(index = 0 ; index < table->hashtable_size ; index ++) {
226 if (table->table[index].data != NULL) {
227 func(table->table[index].hash, data);
228 for(cur = table->table[index].next ; cur != NULL ; cur = cur->next)
229 func(cur->hash, data);
230 }
231 }
232}
233
234void cinthash_foreach_data(cinthash_t * table,
235 void (* func)(void *, void *),
236 void * data)
237{
238 unsigned long index;
239 struct cinthash_list * cur;
240
241 for(index = 0 ; index < table->hashtable_size ; index ++) {
242 if (table->table[index].data != NULL) {
243 func(table->table[index].data, data);
244 for(cur = table->table[index].next ; cur != NULL ; cur = cur->next)
245 func(cur->data, data);
246 }
247 }
248}
diff --git a/kmicromail/libetpan/tools/cinthash.h b/kmicromail/libetpan/tools/cinthash.h
new file mode 100644
index 0000000..7e59dff
--- a/dev/null
+++ b/kmicromail/libetpan/tools/cinthash.h
@@ -0,0 +1,69 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef CINTHASH_H
37
38#define CINTHASH_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44typedef struct cinthash_t {
45 struct cinthash_list * table;
46 unsigned long hashtable_size ;
47 unsigned long count;
48} cinthash_t;
49
50cinthash_t * cinthash_new(unsigned long hashtable_size);
51void cinthash_free(cinthash_t * table);
52
53int cinthash_add(cinthash_t * table, unsigned long hash, void * data);
54int cinthash_remove(cinthash_t * table, unsigned long hash);
55void * cinthash_find(cinthash_t * table, unsigned long hash);
56
57void cinthash_foreach_key(cinthash_t * table,
58 void (* func)(unsigned long, void *),
59 void * data);
60
61void cinthash_foreach_data(cinthash_t * table,
62 void (* fun)(void *, void *),
63 void * data);
64
65#ifdef __cplusplus
66}
67#endif
68
69#endif
diff --git a/kmicromail/libetpan/tools/clist.c b/kmicromail/libetpan/tools/clist.c
new file mode 100644
index 0000000..e5c680d
--- a/dev/null
+++ b/kmicromail/libetpan/tools/clist.c
@@ -0,0 +1,266 @@
1
2/*
3 * libEtPan! -- a mail stuff library
4 *
5 * clist - Implements simple generic double-linked pointer lists
6 *
7 * Copyright (c) 1999-2000, Gaël Roualland <gael.roualland@iname.com>
8 * interface changes - 2002 - DINH Viet Hoa
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the libEtPan! project nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36/*
37 * $Id$
38 */
39
40#include <stdlib.h>
41#include "clist.h"
42
43clist * clist_new() {
44 clist * lst;
45
46 lst = (clist *) malloc(sizeof(clist));
47 if (!lst) return NULL;
48
49 lst->first = lst->last = NULL;
50 lst->count = 0;
51
52 return lst;
53}
54
55void clist_free(clist * lst) {
56 clistcell * l1, * l2;
57
58 l1 = lst->first;
59 while (l1) {
60 l2 = l1->next;
61 free(l1);
62 l1 = l2;
63 }
64
65 free(lst);
66}
67
68#ifdef NO_MACROS
69int clist_isempty(clist * lst) {
70 return ((lst->first==lst->last) && (lst->last==NULL));
71}
72
73clistiter * clist_begin(clist * lst) {
74 return lst->first;
75}
76
77clistiter * clist_end(clist * lst) {
78 return lst->last;
79}
80
81clistiter * clist_next(clistiter * iter) {
82 if (iter)
83 return iter->next;
84 else
85 return NULL;
86}
87
88clistiter * clist_previous(clistiter * iter) {
89 if (iter)
90 return iter->previous;
91 else
92 return NULL;
93}
94
95void * clist_content(clistiter * iter) {
96 if (iter)
97 return iter->data;
98 else
99 return NULL;
100}
101
102int clist_count(clist * lst) {
103 return lst->count;
104}
105
106int clist_prepend(clist * lst, void * data) {
107 return clist_insert_before(lst, lst->first, data);
108}
109
110int clist_append(clist * lst, void * data) {
111 return clist_insert_after(lst, lst->last, data);
112}
113#endif
114
115int clist_insert_before(clist * lst, clistiter * iter, void * data) {
116 clistcell * c;
117
118 c = (clistcell *) malloc(sizeof(clistcell));
119 if (!c) return -1;
120
121 c->data = data;
122 lst->count++;
123
124 if (clist_isempty(lst)) {
125 c->previous = c->next = NULL;
126 lst->first = lst->last = c;
127 return 0;
128 }
129
130 if (!iter) {
131 c->previous = lst->last;
132 c->previous->next = c;
133 c->next = NULL;
134 lst->last = c;
135 return 0;
136 }
137
138 c->previous = iter->previous;
139 c->next = iter;
140 c->next->previous = c;
141 if (c->previous)
142 c->previous->next = c;
143 else
144 lst->first = c;
145
146 return 0;
147}
148
149int clist_insert_after(clist * lst, clistiter * iter, void * data) {
150 clistcell * c;
151
152 c = (clistcell *) malloc(sizeof(clistcell));
153 if (!c) return -1;
154
155 c->data = data;
156 lst->count++;
157
158 if (clist_isempty(lst)) {
159 c->previous = c->next = NULL;
160 lst->first = lst->last = c;
161 return 0;
162 }
163
164 if (!iter) {
165 c->previous = lst->last;
166 c->previous->next = c;
167 c->next = NULL;
168 lst->last = c;
169 return 0;
170 }
171
172 c->previous = iter;
173 c->next = iter->next;
174 if (c->next)
175 c->next->previous = c;
176 else
177 lst->last = c;
178 c->previous->next = c;
179
180 return 0;
181}
182
183clistiter * clist_delete(clist * lst, clistiter * iter) {
184 clistiter * ret;
185
186 if (!iter) return NULL;
187
188 if (iter->previous)
189 iter->previous->next = iter->next;
190 else
191 lst->first = iter->next;
192
193 if (iter->next) {
194 iter->next->previous = iter->previous;
195 ret = iter->next;
196 } else {
197 lst->last = iter->previous;
198 ret = NULL;
199 }
200
201 free(iter);
202 lst->count--;
203
204 return ret;
205}
206
207
208
209void clist_foreach(clist * lst, clist_func func, void * data)
210{
211 clistiter * cur;
212
213 for(cur = clist_begin(lst) ; cur != NULL ; cur = cur->next)
214 func(cur->data, data);
215}
216
217void clist_concat(clist * dest, clist * src)
218{
219 if (src->first == NULL) {
220 /* do nothing */
221 }
222 else if (dest->last == NULL) {
223 dest->first = src->first;
224 dest->last = src->last;
225 }
226 else {
227 dest->last->next = src->first;
228 src->first->previous = dest->last;
229 dest->last = src->last;
230 }
231
232 dest->count += src->count;
233 src->last = src->first = NULL;
234}
235
236static inline clistiter * internal_clist_nth(clist * lst, int index)
237{
238 clistiter * cur;
239
240 cur = clist_begin(lst);
241 while ((index > 0) && (cur != NULL)) {
242 cur = cur->next;
243 index --;
244 }
245
246 if (cur == NULL)
247 return NULL;
248
249 return cur;
250}
251
252void * clist_nth_data(clist * lst, int index)
253{
254 clistiter * cur;
255
256 cur = internal_clist_nth(lst, index);
257 if (cur == NULL)
258 return NULL;
259
260 return cur->data;
261}
262
263clistiter * clist_nth(clist * lst, int index)
264{
265 return internal_clist_nth(lst, index);
266}
diff --git a/kmicromail/libetpan/tools/clist.h b/kmicromail/libetpan/tools/clist.h
new file mode 100644
index 0000000..bd97f59
--- a/dev/null
+++ b/kmicromail/libetpan/tools/clist.h
@@ -0,0 +1,134 @@
1
2/*
3 * libEtPan! -- a mail stuff library
4 *
5 * clist - Implements simple generic double-linked pointer lists
6 *
7 * Copyright (c) 1999-2000, Gaël Roualland <gael.roualland@iname.com>
8 * interface changes - 2002 - DINH Viet Hoa
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the libEtPan! project nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36/*
37 * $Id$
38 */
39
40#ifndef CLIST_H
41#define CLIST_H
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47typedef struct clistcell_s {
48 void * data;
49 struct clistcell_s * previous;
50 struct clistcell_s * next;
51} clistcell;
52
53struct clist_s {
54 clistcell * first;
55 clistcell * last;
56 int count;
57};
58
59typedef struct clist_s clist;
60typedef clistcell clistiter;
61
62/* Allocate a new pointer list */
63clist * clist_new();
64
65/* Destroys a list. Data pointed by data pointers is NOT freed. */
66void clist_free(clist *);
67
68/* Some of the following routines can be implemented as macros to
69 be faster. If you don't want it, define NO_MACROS */
70#ifdef NO_MACROS
71
72/* Returns TRUE if list is empty */
73int clist_isempty(clist *);
74
75/* Returns the number of elements in the list */
76int clist_count(clist *);
77
78/* Returns an iterator to the first element of the list */
79clistiter * clist_begin(clist *);
80
81/* Returns an iterator to the last element of the list */
82clistiter * clist_end(clist *);
83
84/* Returns an iterator to the next element of the list */
85clistiter * clist_next(clistiter *);
86
87/* Returns an iterator to the previous element of the list */
88clistiter * clist_previous(clistiter *);
89
90/* Returns the data pointer of this element of the list */
91void* clist_content(clistiter *);
92
93/* Inserts this data pointer at the beginning of the list */
94int clist_prepend(clist *, void *);
95
96/* Inserts this data pointer at the end of the list */
97int clist_append(clist *, void *);
98#else
99#define clist_isempty(lst) ((lst->first==lst->last) && (lst->last==NULL))
100#define clist_count(lst) (lst->count)
101#define clist_begin(lst) (lst->first)
102#define clist_end(lst) (lst->last)
103#define clist_next(iter) (iter ? iter->next : NULL)
104#define clist_previous(iter) (iter ? iter->previous : NULL)
105#define clist_content(iter) (iter ? iter->data : NULL)
106#define clist_prepend(lst, data) (clist_insert_before(lst, lst->first, data))
107#define clist_append(lst, data) (clist_insert_after(lst, lst->last, data))
108#endif
109
110/* Inserts this data pointer before the element pointed by the iterator */
111int clist_insert_before(clist *, clistiter *, void *);
112
113/* Inserts this data pointer after the element pointed by the iterator */
114int clist_insert_after(clist *, clistiter *, void *);
115
116/* Deletes the element pointed by the iterator.
117 Returns an iterator to the next element. */
118clistiter * clist_delete(clist *, clistiter *);
119
120typedef void (* clist_func)(void *, void *);
121
122void clist_foreach(clist * lst, clist_func func, void * data);
123
124void clist_concat(clist * dest, clist * src);
125
126void * clist_nth_data(clist * lst, int index);
127
128clistiter * clist_nth(clist * lst, int index);
129
130#ifdef __cplusplus
131}
132#endif
133
134#endif
diff --git a/kmicromail/libetpan/tools/connect.c b/kmicromail/libetpan/tools/connect.c
new file mode 100644
index 0000000..c67c18c
--- a/dev/null
+++ b/kmicromail/libetpan/tools/connect.c
@@ -0,0 +1,86 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "connect.h"
37
38#include <sys/types.h>
39#include <string.h>
40#include <netdb.h>
41#include <netinet/in.h>
42#include <sys/socket.h>
43#include <unistd.h>
44
45uint16_t mail_get_service_port(const char * name, char * protocol)
46{
47 struct servent * service;
48
49 service = getservbyname(name, protocol);
50
51 if (service == NULL)
52 return 0;
53
54 return service->s_port;
55}
56
57int mail_tcp_connect(const char * server, uint16_t port)
58{
59 struct hostent * remotehost;
60 struct sockaddr_in sa;
61 int s;
62 int r;
63
64 s = socket(PF_INET, SOCK_STREAM, 0);
65 if (s == -1)
66 goto err;
67
68 remotehost = gethostbyname(server);
69 if (remotehost == NULL)
70 goto close_socket;
71
72 sa.sin_family = AF_INET;
73 sa.sin_port = htons(port);
74 memcpy(&sa.sin_addr, remotehost->h_addr, remotehost->h_length);
75
76 r = connect(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in));
77 if (r == -1)
78 goto close_socket;
79
80 return s;
81
82 close_socket:
83 close(s);
84 err:
85 return -1;
86}
diff --git a/kmicromail/libetpan/tools/connect.h b/kmicromail/libetpan/tools/connect.h
new file mode 100644
index 0000000..9e44501
--- a/dev/null
+++ b/kmicromail/libetpan/tools/connect.h
@@ -0,0 +1,54 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef CONNECT_H
37
38#define CONNECT_H
39
40#include <inttypes.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46uint16_t mail_get_service_port(const char * name, char * protocol);
47int mail_tcp_connect(const char * server, uint16_t port);
48
49#ifdef __cplusplus
50}
51#endif
52
53#endif
54
diff --git a/kmicromail/libetpan/tools/hmac-md5.h b/kmicromail/libetpan/tools/hmac-md5.h
new file mode 100644
index 0000000..2ae6098
--- a/dev/null
+++ b/kmicromail/libetpan/tools/hmac-md5.h
@@ -0,0 +1,94 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/* hmac-md5.h -- HMAC_MD5 functions
33 */
34
35/*
36 * $Id$
37 */
38
39#ifndef HMAC_MD5_H
40#define HMAC_MD5_H 1
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46#define HMAC_MD5_SIZE 16
47
48/* intermediate MD5 context */
49typedef struct HMAC_MD5_CTX_s {
50 MD5_CTX ictx, octx;
51} HMAC_MD5_CTX;
52
53/* intermediate HMAC state
54 * values stored in network byte order (Big Endian)
55 */
56typedef struct HMAC_MD5_STATE_s {
57 UINT4 istate[4];
58 UINT4 ostate[4];
59} HMAC_MD5_STATE;
60
61/* One step hmac computation
62 *
63 * digest may be same as text or key
64 */
65void hmac_md5(const unsigned char *text, int text_len,
66 const unsigned char *key, int key_len,
67 unsigned char digest[HMAC_MD5_SIZE]);
68
69/* create context from key
70 */
71void hmac_md5_init(HMAC_MD5_CTX *hmac,
72 const unsigned char *key, int key_len);
73
74/* precalculate intermediate state from key
75 */
76void hmac_md5_precalc(HMAC_MD5_STATE *hmac,
77 const unsigned char *key, int key_len);
78
79/* initialize context from intermediate state
80 */
81void hmac_md5_import(HMAC_MD5_CTX *hmac, HMAC_MD5_STATE *state);
82
83#define hmac_md5_update(hmac, text, text_len) MD5Update(&(hmac)->ictx, (text), (text_len))
84
85/* finish hmac from intermediate result. Intermediate result is zeroed.
86 */
87void hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE],
88 HMAC_MD5_CTX *hmac);
89
90#ifdef __cplusplus
91}
92#endif
93
94#endif /* HMAC_MD5_H */
diff --git a/kmicromail/libetpan/tools/mail.h b/kmicromail/libetpan/tools/mail.h
new file mode 100644
index 0000000..d4c63c4
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mail.h
@@ -0,0 +1,56 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAIL_H
37
38#define MAIL_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#ifndef TRUE
45#define TRUE 1
46#endif
47
48#ifndef FALSE
49#define FALSE 0
50#endif
51
52#ifdef __cplusplus
53}
54#endif
55
56#endif
diff --git a/kmicromail/libetpan/tools/mail_cache_db.c b/kmicromail/libetpan/tools/mail_cache_db.c
new file mode 100644
index 0000000..5b6e9c9
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mail_cache_db.c
@@ -0,0 +1,364 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mail_cache_db.h"
37
38#include <sys/types.h>
39#include <sys/stat.h>
40#include <fcntl.h>
41#include <stdlib.h>
42#include <string.h>
43
44#ifndef CONFIG_H
45#define CONFIG_H
46#include "config.h"
47#endif
48
49#include "libetpan-config.h"
50
51#include "maillock.h"
52
53#if DBVERS >= 1
54#include <db.h>
55#endif
56
57#if DBVERS >= 1
58static struct mail_cache_db * mail_cache_db_new(DB * db)
59{
60 struct mail_cache_db * cache_db;
61
62 cache_db = malloc(sizeof(* cache_db));
63 if (cache_db == NULL)
64 return NULL;
65 cache_db->internal_database = db;
66
67 return cache_db;
68}
69
70static void mail_cache_db_free(struct mail_cache_db * cache_db)
71{
72 free(cache_db);
73}
74#endif
75
76int mail_cache_db_open(const char * filename,
77 struct mail_cache_db ** pcache_db)
78{
79#if DBVERS >= 1
80 DB * dbp;
81 int r;
82 struct mail_cache_db * cache_db;
83
84#if DB_VERSION_MAJOR >= 3
85 r = db_create(&dbp, NULL, 0);
86 if (r != 0)
87 goto err;
88
89#if (DB_VERSION_MAJOR >= 4) && ((DB_VERSION_MAJOR > 4) || (DB_VERSION_MINOR >= 1))
90 r = dbp->open(dbp, NULL, filename, NULL, DB_BTREE, DB_CREATE,
91 S_IRUSR | S_IWUSR);
92#else
93 r = dbp->open(dbp, filename, NULL, DB_BTREE, DB_CREATE, S_IRUSR | S_IWUSR);
94#endif
95 if (r != 0)
96 goto close_db;
97#else
98#if DBVERS > 1
99 r = db_open(filename, DB_BTREE, DB_CREATE, S_IRUSR | S_IWUSR,
100 NULL, NULL, &dbp);
101 if (r != 0)
102 goto err;
103#elif DBVERS == 1
104 dbp = dbopen(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, DB_BTREE, NULL);
105 if (dbp == NULL)
106 goto err;
107#else
108 goto err;
109#endif
110#endif
111
112 cache_db = mail_cache_db_new(dbp);
113 if (cache_db == NULL)
114 goto close_db;
115
116 * pcache_db = cache_db;
117
118 return 0;
119
120 close_db:
121#if DBVERS > 1
122 dbp->close(cache_db->internal_database, 0);
123#elif DBVERS == 1
124 dbp->close(cache_db->internal_database);
125#endif
126 err:
127 return -1;
128#else
129 return -1;
130#endif
131}
132
133void mail_cache_db_close(struct mail_cache_db * cache_db)
134{
135#if DBVERS >= 1
136 DB * dbp;
137
138 dbp = cache_db->internal_database;
139
140#if DBVERS > 1
141 dbp->close(cache_db->internal_database, 0);
142#elif DBVERS == 1
143 dbp->close(cache_db->internal_database);
144#endif
145
146 mail_cache_db_free(cache_db);
147#endif
148}
149
150int mail_cache_db_open_lock(const char * filename,
151 struct mail_cache_db ** pcache_db)
152{
153 int r;
154 struct mail_cache_db * cache_db;
155
156 r = maillock_write_lock(filename, -1);
157 if (r < 0)
158 goto err;
159
160 r = mail_cache_db_open(filename, &cache_db);
161 if (r < 0)
162 goto unlock;
163
164 * pcache_db = cache_db;
165
166 return 0;
167
168 unlock:
169 maillock_write_unlock(filename, -1);
170 err:
171 return -1;
172}
173
174void mail_cache_db_close_unlock(const char * filename,
175 struct mail_cache_db * cache_db)
176{
177 maillock_write_unlock(filename, -1);
178 mail_cache_db_close(cache_db);
179}
180
181
182int mail_cache_db_put(struct mail_cache_db * cache_db,
183 const void * key, size_t key_len, const void * value, size_t value_len)
184{
185#if DBVERS >= 1
186 int r;
187 DBT db_key;
188 DBT db_data;
189 DB * dbp;
190
191 dbp = cache_db->internal_database;
192
193 memset(&db_key, 0, sizeof(db_key));
194 memset(&db_data, 0, sizeof(db_data));
195 db_key.data = (void *) key;
196 db_key.size = key_len;
197 db_data.data = (void *) value;
198 db_data.size = value_len;
199
200#if DBVERS > 1
201 r = dbp->put(dbp, NULL, &db_key, &db_data, 0);
202#elif DBVERS == 1
203 r = dbp->put(dbp, &db_key, &db_data, 0);
204#else
205 r = -1;
206#endif
207
208 return r;
209#else
210 return -1;
211#endif
212}
213
214int mail_cache_db_get(struct mail_cache_db * cache_db,
215 const void * key, size_t key_len, void ** pvalue, size_t * pvalue_len)
216{
217#if DBVERS >= 1
218 int r;
219 DBT db_key;
220 DBT db_data;
221 DB * dbp;
222
223 dbp = cache_db->internal_database;
224
225 memset(&db_key, 0, sizeof(db_key));
226 memset(&db_data, 0, sizeof(db_data));
227 db_key.data = (void *) key;
228 db_key.size = key_len;
229
230#if DBVERS > 1
231 r = dbp->get(dbp, NULL, &db_key, &db_data, 0);
232#elif DBVERS == 1
233 r = dbp->get(dbp, &db_key, &db_data, 0);
234#else
235 r = -1;
236#endif
237
238 if (r != 0)
239 return r;
240
241 * pvalue = db_data.data;
242 * pvalue_len = db_data.size;
243
244 return 0;
245#else
246 return -1;
247#endif
248}
249
250int mail_cache_db_del(struct mail_cache_db * cache_db,
251 const void * key, size_t key_len)
252{
253#if DBVERS >= 1
254 int r;
255 DBT db_key;
256 DB * dbp;
257
258 dbp = cache_db->internal_database;
259
260 memset(&db_key, 0, sizeof(db_key));
261 db_key.data = (void *) key;
262 db_key.size = key_len;
263
264#if DBVERS > 1
265 r = dbp->del(dbp, NULL, &db_key, 0);
266#elif DBVERS == 1
267 r = dbp->del(dbp, &db_key, 0);
268#else
269 r = -1;
270#endif
271
272 return r;
273#else
274 return -1;
275#endif
276}
277
278#if DBVERS > 1
279int mail_cache_db_clean_up(struct mail_cache_db * cache_db,
280 chash * exist)
281{
282 DB * dbp;
283 int r;
284 DBC * dbcp;
285 DBT db_key;
286 DBT db_data;
287
288 dbp = cache_db->internal_database;
289
290 r = dbp->cursor(dbp, NULL, &dbcp, 0);
291 if (r != 0)
292 return r;
293
294 memset(&db_key, 0, sizeof(db_key));
295 memset(&db_data, 0, sizeof(db_data));
296
297 while (1) {
298 chashdatum hash_key;
299 chashdatum hash_data;
300
301 r = dbcp->c_get(dbcp, &db_key, &db_data, DB_NEXT);
302 if (r != 0)
303 break;
304
305 hash_key.data = db_key.data;
306 hash_key.len = db_key.size;
307
308 r = chash_get(exist, &hash_key, &hash_data);
309 if (r < 0) {
310 r = dbcp->c_del(dbcp, 0);
311 if (r != 0)
312 return r;
313 }
314 }
315
316 r = dbcp->c_close(dbcp);
317 if (r != 0)
318 return r;
319
320 return 0;
321}
322#elif DBVERS == 1
323int mail_cache_db_clean_up(struct mail_cache_db * cache_db,
324 chash * exist)
325{
326 DB * dbp;
327 int r;
328 DBT db_key;
329 DBT db_data;
330
331 dbp = cache_db->internal_database;
332
333 r = dbp->seq(dbp, &db_key, &db_data, R_FIRST);
334 if (r == -1)
335 return r;
336
337 while (r == 0) {
338 chashdatum hash_key;
339 chashdatum hash_data;
340
341 hash_key.data = db_key.data;
342 hash_key.len = db_key.size;
343
344 r = chash_get(exist, &hash_key, &hash_data);
345 if (r < 0) {
346 r = dbp->del(dbp, &db_key, 0);
347 if (r != 0)
348 return r;
349 }
350
351 r = dbp->seq(dbp, &db_key, &db_data, R_NEXT);
352 if (r == -1)
353 return r;
354 }
355
356 return 0;
357}
358#else
359int mail_cache_db_clean_up(struct mail_cache_db * cache_db,
360 chash * exist)
361{
362 return -1;
363}
364#endif
diff --git a/kmicromail/libetpan/tools/mail_cache_db.h b/kmicromail/libetpan/tools/mail_cache_db.h
new file mode 100644
index 0000000..0ca17d9
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mail_cache_db.h
@@ -0,0 +1,138 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAIL_CACHE_DB_H
37
38#define MAIL_CACHE_DB_H
39
40#include <sys/types.h>
41#include "mail_cache_db_types.h"
42#include "chash.h"
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48/*
49 this module will handle a database "f(key) -> value" in a file
50
51 berkeley DB or other can be used for implementation of low-level file.
52*/
53
54/*
55 mail_cache_db_open()
56
57 This function opens the file "filename".
58 The pointer return in pcache_db should be used for further references
59 to the database.
60*/
61
62int mail_cache_db_open(const char * filename,
63 struct mail_cache_db ** pcache_db);
64
65/*
66 mail_cache_db_close()
67
68 This function closes the opened database.
69 The pointer cannot be used later.
70*/
71
72void mail_cache_db_close(struct mail_cache_db * cache_db);
73
74/*
75 mail_cache_db_open_lock()
76
77 This function opens and locks the file "filename".
78 The pointer return in pcache_db should be used for further references
79 to the database.
80*/
81
82int mail_cache_db_open_lock(const char * filename,
83 struct mail_cache_db ** pcache_db);
84
85/*
86 mail_cache_db_open_unlock()
87
88 This function closes and unlocks the opened database.
89 The pointer cannot be used later.
90*/
91
92void mail_cache_db_close_unlock(const char * filename,
93 struct mail_cache_db * cache_db);
94
95/*
96 mail_cache_db_put()
97
98 This function will store a given key and value in the database.
99*/
100
101int mail_cache_db_put(struct mail_cache_db * cache_db,
102 const void * key, size_t key_len, const void * value, size_t value_len);
103
104/*
105 mail_cache_db_get()
106
107 This function will retrieve the value corresponding to a given key
108 from the database.
109*/
110
111int mail_cache_db_get(struct mail_cache_db * cache_db,
112 const void * key, size_t key_len, void ** pvalue, size_t * pvalue_len);
113
114/*
115 mail_cache_db_del()
116
117 This function will delete the given key and the corresponding value
118 from the database.
119*/
120
121int mail_cache_db_del(struct mail_cache_db * cache_db,
122 const void * key, size_t key_len);
123
124/*
125 mail_cache_clean_up()
126
127 This function will delete the key all the key/value pairs of the
128 database file which key does not exist in the given hash.
129*/
130
131int mail_cache_db_clean_up(struct mail_cache_db * cache_db,
132 chash * exist);
133
134#ifdef __cplusplus
135}
136#endif
137
138#endif
diff --git a/kmicromail/libetpan/tools/mail_cache_db_types.h b/kmicromail/libetpan/tools/mail_cache_db_types.h
new file mode 100644
index 0000000..f346c5f
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mail_cache_db_types.h
@@ -0,0 +1,52 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAIL_CACHE_DB_TYPES_H
37
38#define MAIL_CACHE_DB_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44struct mail_cache_db {
45 void * internal_database;
46};
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/kmicromail/libetpan/tools/maillock.c b/kmicromail/libetpan/tools/maillock.c
new file mode 100644
index 0000000..6128f34
--- a/dev/null
+++ b/kmicromail/libetpan/tools/maillock.c
@@ -0,0 +1,286 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id $
34 */
35
36#include "maillock.h"
37
38#include "libetpan-config.h"
39
40#include <sys/types.h>
41#include <sys/stat.h>
42#include <fcntl.h>
43#include <unistd.h>
44#include <stdio.h>
45#include <time.h>
46#include <string.h>
47
48/* ********************************************************************** */
49
50/* lock primitives */
51
52/* the lock code is modified from the dot lock file code from mail.local.c */
53
54/*
55 SENDMAIL LICENSE
56
57The following license terms and conditions apply, unless a different
58license is obtained from Sendmail, Inc., 6425 Christie Ave, Fourth Floor,
59Emeryville, CA 94608, or by electronic mail at license@sendmail.com.
60
61License Terms:
62
63Use, Modification and Redistribution (including distribution of any
64modified or derived work) in source and binary forms is permitted only if
65each of the following conditions is met:
66
671. Redistributions qualify as "freeware" or "Open Source Software" under
68 one of the following terms:
69
70 (a) Redistributions are made at no charge beyond the reasonable cost of
71 materials and delivery.
72
73 (b) Redistributions are accompanied by a copy of the Source Code or by an
74 irrevocable offer to provide a copy of the Source Code for up to three
75 years at the cost of materials and delivery. Such redistributions
76 must allow further use, modification, and redistribution of the Source
77 Code under substantially the same terms as this license. For the
78 purposes of redistribution "Source Code" means the complete compilable
79 and linkable source code of sendmail including all modifications.
80
812. Redistributions of source code must retain the copyright notices as they
82 appear in each source code file, these license terms, and the
83 disclaimer/limitation of liability set forth as paragraph 6 below.
84
853. Redistributions in binary form must reproduce the Copyright Notice,
86 these license terms, and the disclaimer/limitation of liability set
87 forth as paragraph 6 below, in the documentation and/or other materials
88 provided with the distribution. For the purposes of binary distribution
89 the "Copyright Notice" refers to the following language:
90 "Copyright (c) 1998-2002 Sendmail, Inc. All rights reserved."
91
924. Neither the name of Sendmail, Inc. nor the University of California nor
93 the names of their contributors may be used to endorse or promote
94 products derived from this software without specific prior written
95 permission. The name "sendmail" is a trademark of Sendmail, Inc.
96
975. All redistributions must comply with the conditions imposed by the
98 University of California on certain embedded code, whose copyright
99 notice and conditions for redistribution are as follows:
100
101 (a) Copyright (c) 1988, 1993 The Regents of the University of
102 California. All rights reserved.
103
104 (b) Redistribution and use in source and binary forms, with or without
105 modification, are permitted provided that the following conditions
106 are met:
107
108 (i) Redistributions of source code must retain the above copyright
109 notice, this list of conditions and the following disclaimer.
110
111 (ii) Redistributions in binary form must reproduce the above
112 copyright notice, this list of conditions and the following
113 disclaimer in the documentation and/or other materials provided
114 with the distribution.
115
116 (iii) Neither the name of the University nor the names of its
117 contributors may be used to endorse or promote products derived
118 from this software without specific prior written permission.
119
1206. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY
121 SENDMAIL, INC. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
122 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
123 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
124 NO EVENT SHALL SENDMAIL, INC., THE REGENTS OF THE UNIVERSITY OF
125 CALIFORNIA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
126 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
127 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
128 USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
129 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
130 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
131 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
132*/
133
134/*
135 TODO : lock, prefer fcntl() over flock()
136 AND use dotlock code above
137*/
138
139 #define LOCKTO_RM 300/* timeout for stale lockfile removal */
140 #define LOCKTO_GLOB 400/* global timeout for lockfile creation */
141
142static int lock_common(const char * filename, int fd, short locktype)
143{
144 char lockfilename[PATH_MAX];
145 struct flock lock;
146 /* dot lock file */
147 int statfailed = 0;
148 time_t start;
149 int r;
150 int res;
151
152 lock.l_start = 0;
153 lock.l_len = 0;
154 lock.l_pid = getpid();
155 lock.l_type = locktype;
156 lock.l_whence = SEEK_SET;
157
158 r = fcntl(fd, F_SETLKW, &lock);
159 if (r < 0) {
160 /* WARNING POSIX lock could not be applied */
161 }
162
163 /* dot lock file */
164
165 if (strlen(filename) + 6 > PATH_MAX) {
166 res = -1;
167 goto unlock;
168 }
169
170 snprintf(lockfilename, PATH_MAX, "%s.lock", filename);
171
172 time(&start);
173 while (1) {
174 int fd;
175 struct stat st;
176 time_t now;
177
178 /* global timeout */
179 time(&now);
180 if (now > start + LOCKTO_GLOB) {
181 res = -1;
182 goto unlock;
183 }
184
185 fd = open(lockfilename, O_WRONLY|O_EXCL|O_CREAT, 0);
186 if (fd >= 0) {
187 /* defeat lock checking programs which test pid */
188 write(fd, "0", 2);
189 close(fd);
190 break;
191 }
192
193 /* libEtPan! - adds a delay of 5 seconds between each tries */
194 sleep(5);
195
196 if (stat(lockfilename, &st) < 0) {
197 if (statfailed++ > 5) {
198 res = -1;
199 goto unlock;
200 }
201 continue;
202 }
203 statfailed = 0;
204 time(&now);
205
206 if (now < st.st_ctime + LOCKTO_RM)
207 continue;
208
209 /* try to remove stale lockfile */
210 if (unlink(lockfilename) < 0) {
211 res = -1;
212 goto unlock;
213 }
214
215 /*
216 libEtPan! - removes this delay of 5 seconds,
217 maybe it was misplaced ?
218 */
219#if 0
220 sleep(5);
221#endif
222 }
223
224 return 0;
225
226 unlock:
227 lock.l_start = 0;
228 lock.l_len = 0;
229 lock.l_pid = getpid();
230 lock.l_type = F_UNLCK;
231 lock.l_whence = SEEK_SET;
232
233 r = fcntl(fd, F_SETLK, &lock);
234 if (r < 0) {
235 /* WARNING POSIX lock could not be applied */
236 }
237 err:
238 return res;
239}
240
241static int unlock_common(const char * filename, int fd)
242{
243 char lockfilename[PATH_MAX];
244 struct flock lock;
245 int r;
246
247 if (strlen(filename) + 6 > PATH_MAX)
248 return -1;
249
250 snprintf(lockfilename, PATH_MAX, "%s.lock", filename);
251
252 unlink(lockfilename);
253
254 lock.l_start = 0;
255 lock.l_len = 0;
256 lock.l_pid = getpid();
257 lock.l_type = F_UNLCK;
258 lock.l_whence = SEEK_SET;
259
260 r = fcntl(fd, F_SETLK, &lock);
261 if (r < 0) {
262 /* WARNING POSIX lock could not be applied */
263 }
264
265 return 0;
266}
267
268int maillock_read_lock(const char * filename, int fd)
269{
270 return lock_common(filename, fd, F_RDLCK);
271}
272
273int maillock_read_unlock(const char * filename, int fd)
274{
275 return unlock_common(filename, fd);
276}
277
278int maillock_write_lock(const char * filename, int fd)
279{
280 return lock_common(filename, fd, F_WRLCK);
281}
282
283int maillock_write_unlock(const char * filename, int fd)
284{
285 return unlock_common(filename, fd);
286}
diff --git a/kmicromail/libetpan/tools/maillock.h b/kmicromail/libetpan/tools/maillock.h
new file mode 100644
index 0000000..2f64e35
--- a/dev/null
+++ b/kmicromail/libetpan/tools/maillock.h
@@ -0,0 +1,53 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILLOCK_H
37
38#define MAILLOCK_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44int maillock_read_lock(const char * filename, int fd);
45int maillock_read_unlock(const char * filename, int fd);
46int maillock_write_lock(const char * filename, int fd);
47int maillock_write_unlock(const char * filename, int fd);
48
49#ifdef __cplusplus
50}
51#endif
52
53#endif
diff --git a/kmicromail/libetpan/tools/mailstream.c b/kmicromail/libetpan/tools/mailstream.c
new file mode 100644
index 0000000..0f55e67
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mailstream.c
@@ -0,0 +1,394 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailstream.h"
37#include "maillock.h"
38#include <string.h>
39#include <stdlib.h>
40#include <sys/types.h>
41#include <sys/stat.h>
42
43#define DEFAULT_NETWORK_TIMEOUT 300
44
45#ifdef LIBETPAN_MAILSTREAM_DEBUG
46
47#define STREAM_DEBUG
48
49#include <stdio.h>
50
51#define LOG_FILE "libetpan-stream-debug.log"
52
53int mailstream_debug = 0;
54
55#define STREAM_LOG_BUF(buf, size) \
56 if (mailstream_debug) { \
57 FILE * f; \
58 mode_t old_mask; \
59 \
60 old_mask = umask(0077); \
61 f = fopen(LOG_FILE, "a"); \
62 umask(old_mask); \
63 if (f != NULL) { \
64 maillock_write_lock(LOG_FILE, fileno(f)); \
65 fwrite((buf), 1, (size), f); \
66 maillock_write_unlock(LOG_FILE, fileno(f)); \
67 fclose(f); \
68 } \
69 }
70
71#define STREAM_LOG(str) \
72 if (mailstream_debug) { \
73 FILE * f; \
74 mode_t old_mask; \
75 \
76 old_mask = umask(0077); \
77 f = fopen(LOG_FILE, "a"); \
78 umask(old_mask); \
79 if (f != NULL) { \
80 maillock_write_lock(LOG_FILE, fileno(f)); \
81 fputs((str), f); \
82 maillock_write_unlock(LOG_FILE, fileno(f)); \
83 fclose(f); \
84 } \
85 }
86
87#else
88
89#define STREAM_LOG_BUF(buf, size) do { } while (0)
90#define STREAM_LOG(buf) do { } while (0)
91
92#endif
93
94
95mailstream * mailstream_new(mailstream_low * low, size_t buffer_size)
96{
97 mailstream * s;
98
99 s = malloc(sizeof(* s));
100 if (s == NULL)
101 goto err;
102
103 s->read_buffer = malloc(buffer_size);
104 if (s->read_buffer == NULL)
105 goto free_s;
106 s->read_buffer_len = 0;
107
108 s->write_buffer = malloc(buffer_size);
109 if (s->write_buffer == NULL)
110 goto free_read_buffer;
111 s->write_buffer_len = 0;
112
113 s->buffer_max_size = buffer_size;
114 s->low = low;
115
116 return s;
117
118 free_read_buffer:
119 free(s->read_buffer);
120 free_s:
121 free(s);
122 err:
123 return NULL;
124}
125
126static size_t write_to_internal_buffer(mailstream * s,
127 const void * buf, size_t count)
128{
129 memcpy(s->write_buffer + s->write_buffer_len, buf, count);
130 s->write_buffer_len += count;
131
132 return count;
133}
134
135static size_t write_direct(mailstream * s, const void * buf, size_t count)
136{
137 size_t left;
138 const char * cur_buf;
139 ssize_t written;
140
141 cur_buf = buf;
142 left = count;
143 while (left > 0) {
144 written = mailstream_low_write(s->low, cur_buf, left);
145
146 if (written == -1) {
147 if (count == left)
148 return -1;
149 else
150 return count - left;
151 }
152
153 cur_buf += written;
154 left -= written;
155 }
156
157 return count;
158}
159
160ssize_t mailstream_write(mailstream * s, const void * buf, size_t count)
161{
162 int r;
163
164 if (s == NULL)
165 return -1;
166
167 if (count + s->write_buffer_len > s->buffer_max_size) {
168 r = mailstream_flush(s);
169 if (r == -1)
170 return -1;
171
172 if (count > s->buffer_max_size)
173 return write_direct(s, buf, count);
174 }
175
176#ifdef STREAM_DEBUG
177 STREAM_LOG(">>>>>>> send >>>>>>\n");
178 STREAM_LOG_BUF(buf, count);
179 STREAM_LOG("\n");
180 STREAM_LOG(">>>>>>> end send >>>>>>\n");
181#endif
182
183 return write_to_internal_buffer(s, buf, count);
184}
185
186int mailstream_flush(mailstream * s)
187{
188 char * cur_buf;
189 size_t left;
190 ssize_t written;
191
192 if (s == NULL)
193 return -1;
194
195 cur_buf = s->write_buffer;
196 left = s->write_buffer_len;
197 while (left > 0) {
198 written = mailstream_low_write(s->low, cur_buf, left);
199
200 if (written == -1)
201 goto move_buffer;
202 cur_buf += written;
203 left -= written;
204 }
205
206 s->write_buffer_len = 0;
207
208 return 0;
209
210 move_buffer:
211 memmove(s->write_buffer, cur_buf, left);
212 s->write_buffer_len = left;
213 return -1;
214}
215
216static ssize_t read_from_internal_buffer(mailstream * s,
217 void * buf, size_t count)
218{
219 if (count >= s->read_buffer_len)
220 count = s->read_buffer_len;
221 if (count != 0)
222 memcpy(buf, s->read_buffer, count);
223
224 s->read_buffer_len -= count;
225 if (s->read_buffer_len != 0)
226 memmove(s->read_buffer, s->read_buffer + count,
227 s->read_buffer_len);
228
229 return count;
230}
231
232static ssize_t read_through_buffer(mailstream * s, void * buf, size_t count)
233{
234 size_t left;
235 char * cur_buf;
236 ssize_t bytes_read;
237
238 cur_buf = buf;
239 left = count;
240
241 while (left > 0) {
242 bytes_read = mailstream_low_read(s->low, cur_buf, left);
243
244 if (bytes_read == -1) {
245 if (count == left)
246 return -1;
247 else
248 return count - left;
249 }
250 else if (bytes_read == 0)
251 return count - left;
252
253 cur_buf += bytes_read;
254 left -= bytes_read;
255 }
256
257 return count;
258}
259
260ssize_t mailstream_read(mailstream * s, void * buf, size_t count)
261{
262 ssize_t read_bytes;
263 char * cur_buf;
264 size_t left;
265
266 if (s == NULL)
267 return -1;
268
269 left = count;
270 cur_buf = buf;
271 read_bytes = read_from_internal_buffer(s, cur_buf, left);
272 cur_buf += read_bytes;
273 left -= read_bytes;
274
275 if (left == 0) {
276#ifdef STREAM_DEBUG
277 STREAM_LOG("<<<<<<< read <<<<<<\n");
278 STREAM_LOG_BUF(buf, read_bytes);
279 STREAM_LOG("\n");
280 STREAM_LOG("<<<<<<< end read <<<<<<\n");
281#endif
282
283 return read_bytes;
284 }
285
286 if (left > s->buffer_max_size) {
287 read_bytes = read_through_buffer(s, cur_buf, left);
288 if (read_bytes == -1) {
289 if (count == left)
290 return -1;
291 else {
292
293#ifdef STREAM_DEBUG
294 STREAM_LOG("<<<<<<< read <<<<<<\n");
295 STREAM_LOG_BUF(buf, count - left);
296 STREAM_LOG("\n");
297 STREAM_LOG("<<<<<<< end read <<<<<<\n");
298#endif
299
300 return count - left;
301 }
302 }
303
304 cur_buf += read_bytes;
305 left -= read_bytes;
306
307#ifdef STREAM_DEBUG
308 STREAM_LOG("<<<<<<< read <<<<<<\n");
309 STREAM_LOG_BUF(buf, count - left);
310 STREAM_LOG("\n");
311 STREAM_LOG("<<<<<<< end read <<<<<<\n");
312#endif
313
314 return count - left;
315 }
316
317 read_bytes = mailstream_low_read(s->low, s->read_buffer, s->buffer_max_size);
318 if (read_bytes == -1) {
319 if (left == count)
320 return -1;
321 else {
322#ifdef STREAM_DEBUG
323 STREAM_LOG("<<<<<<< read <<<<<<\n");
324 STREAM_LOG_BUF(buf, count - left);
325 STREAM_LOG("\n");
326 STREAM_LOG("<<<<<<< end read <<<<<<\n");
327#endif
328
329 return count - left;
330 }
331 }
332 else
333 s->read_buffer_len += read_bytes;
334
335 read_bytes = read_from_internal_buffer(s, cur_buf, left);
336 cur_buf += read_bytes;
337 left -= read_bytes;
338
339#ifdef STREAM_DEBUG
340 STREAM_LOG("<<<<<<< read <<<<<<\n");
341 STREAM_LOG_BUF(buf, count - left);
342 STREAM_LOG("\n");
343 STREAM_LOG("<<<<<<< end read <<<<<<\n");
344#endif
345
346 return count - left;
347}
348
349mailstream_low * mailstream_get_low(mailstream * s)
350{
351 return s->low;
352}
353
354void mailstream_set_low(mailstream * s, mailstream_low * low)
355{
356 s->low = low;
357}
358
359int mailstream_close(mailstream * s)
360{
361 mailstream_low_close(s->low);
362 mailstream_low_free(s->low);
363
364 free(s->read_buffer);
365 free(s->write_buffer);
366
367 free(s);
368
369 return 0;
370}
371
372
373
374ssize_t mailstream_feed_read_buffer(mailstream * s)
375{
376 ssize_t read_bytes;
377
378 if (s == NULL)
379 return -1;
380
381 if (s->read_buffer_len == 0) {
382 read_bytes = mailstream_low_read(s->low, s->read_buffer,
383 s->buffer_max_size);
384 if (read_bytes == -1)
385 return -1;
386 s->read_buffer_len += read_bytes;
387 }
388
389 return s->read_buffer_len;
390}
391
392struct timeval mailstream_network_delay =
393 { .tv_sec = DEFAULT_NETWORK_TIMEOUT, .tv_usec = 0 };
394
diff --git a/kmicromail/libetpan/tools/mailstream.h b/kmicromail/libetpan/tools/mailstream.h
new file mode 100644
index 0000000..a4e35cd
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mailstream.h
@@ -0,0 +1,73 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSTREAM_H
37
38#define MAILSTREAM_H
39
40#include <sys/time.h>
41
42#include <libetpan/mailstream_low.h>
43#include <libetpan/mailstream_helper.h>
44#include <libetpan/mailstream_socket.h>
45#include <libetpan/mailstream_ssl.h>
46#include <libetpan/mailstream_types.h>
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52mailstream * mailstream_new(mailstream_low * low, size_t buffer_size);
53ssize_t mailstream_write(mailstream * s, const void * buf, size_t count);
54ssize_t mailstream_read(mailstream * s, void * buf, size_t count);
55int mailstream_close(mailstream * s);
56int mailstream_flush(mailstream * s);
57ssize_t mailstream_feed_read_buffer(mailstream * s);
58mailstream_low * mailstream_get_low(mailstream * s);
59void mailstream_set_low(mailstream * s, mailstream_low * low);
60
61#ifdef LIBETPAN_MAILSTREAM_DEBUG
62extern int mailstream_debug;
63#endif
64
65#define LIBETPAN_MAILSTREAM_NETWORK_DELAY
66extern struct timeval mailstream_network_delay;
67
68#ifdef __cplusplus
69}
70#endif
71
72#endif
73
diff --git a/kmicromail/libetpan/tools/mailstream_helper.c b/kmicromail/libetpan/tools/mailstream_helper.c
new file mode 100644
index 0000000..146f955
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mailstream_helper.c
@@ -0,0 +1,383 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailstream_helper.h"
37#include <string.h>
38#include <stdio.h>
39#include "mail.h"
40
41static void remove_trailing_eol(MMAPString * mmapstr)
42{
43 if (mmapstr->str[mmapstr->len - 1] == '\n') {
44 mmapstr->len --;
45 mmapstr->str[mmapstr->len] = '\0';
46 }
47 if (mmapstr->str[mmapstr->len - 1] == '\r') {
48 mmapstr->len --;
49 mmapstr->str[mmapstr->len] = '\0';
50 }
51}
52
53char * mailstream_read_line(mailstream * stream, MMAPString * line)
54{
55 if (mmap_string_assign(line, "") == NULL)
56 return NULL;
57
58 return mailstream_read_line_append(stream, line);
59}
60
61static char * mailstream_read_len_append(mailstream * stream,
62 MMAPString * line,
63 size_t i)
64{
65 size_t cur_size;
66
67 cur_size = line->len;
68 if (mmap_string_set_size(line, line->len + i) == NULL)
69 return NULL;
70 if (mailstream_read(stream, line->str + cur_size, i) < 0)
71 return NULL;
72 return line->str;
73}
74
75char * mailstream_read_line_append(mailstream * stream, MMAPString * line)
76{
77 if (stream == NULL)
78 return NULL;
79
80 do {
81 if (stream->read_buffer_len > 0) {
82 size_t i;
83
84 i = 0;
85 while (i < stream->read_buffer_len) {
86 if (stream->read_buffer[i] == '\n')
87 return mailstream_read_len_append(stream, line, i + 1);
88 i++;
89 }
90 if (mailstream_read_len_append(stream, line,
91 stream->read_buffer_len) == NULL)
92 return NULL;
93 }
94 else {
95 ssize_t r;
96
97 r = mailstream_feed_read_buffer(stream);
98 if (r == -1)
99 return NULL;
100
101 if (r == 0)
102 break;
103 }
104 }
105 while (1);
106
107 return line->str;
108}
109
110char * mailstream_read_line_remove_eol(mailstream * stream, MMAPString * line)
111{
112 if (!mailstream_read_line(stream, line))
113 return NULL;
114
115 remove_trailing_eol(line);
116
117 return line->str;
118}
119
120int mailstream_is_end_multiline(const char * line)
121{
122 if (line[0] != '.')
123 return FALSE;
124 if (line[1] != 0)
125 return FALSE;
126 return TRUE;
127}
128
129#if 1
130char * mailstream_read_multiline(mailstream * s, size_t size,
131 MMAPString * stream_buffer,
132 MMAPString * multiline_buffer,
133 size_t progr_rate,
134 progress_function * progr_fun)
135{
136 size_t count;
137 char * line;
138 size_t last;
139
140 if (mmap_string_assign(multiline_buffer, "") == NULL)
141 return NULL;
142
143 count = 0;
144 last = 0;
145
146 while ((line = mailstream_read_line_remove_eol(s, stream_buffer)) != NULL) {
147 if (mailstream_is_end_multiline(line))
148 return multiline_buffer->str;
149
150 if (line[0] == '.') {
151 if (mmap_string_append(multiline_buffer, line + 1) == NULL)
152 return NULL;
153 }
154 else {
155 if (mmap_string_append(multiline_buffer, line) == NULL)
156 return NULL;
157 }
158 if (mmap_string_append(multiline_buffer, "\r\n") == NULL)
159 return NULL;
160
161 count += strlen(line);
162 if ((size != 0) && (progr_rate != 0) && (progr_fun != NULL))
163 if (count - last >= progr_rate) {
164 (* progr_fun)(count, size);
165 last = count;
166 }
167 }
168
169 return NULL;
170}
171
172#else
173
174/*
175 high speed but don't replace the line break with '\n' and neither
176 remove the '.'
177*/
178
179static gboolean end_of_multiline(const char * str, gint len)
180{
181 gint index;
182
183 index = len - 1;
184
185 if (str[index] != '\n')
186 return FALSE;
187 if (index == 0)
188 return FALSE;
189
190 index --;
191
192 if (str[index] == '\r') {
193 index --;
194 if (index == 0)
195 return FALSE;
196 }
197
198 if (str[index] != '.')
199 return FALSE;
200 if (index == 0)
201 return FALSE;
202
203 index--;
204
205 if (str[index] != '\n')
206 return FALSE;
207
208 return TRUE;
209}
210
211char * mailstream_read_multiline(mailstream * stream, size_t size,
212 MMAPString * stream_buffer,
213 MMAPString * line,
214 size_t progr_rate,
215 progress_function * progr_fun)
216{
217 if (stream == NULL)
218 return NULL;
219
220 mmap_string_assign(line, "");
221
222 do {
223 if (stream->read_buffer_len > 0) {
224 size_t i;
225
226 i = 0;
227 while (i < stream->read_buffer_len) {
228 if (end_of_multiline(stream->read_buffer, i + 1))
229 return mailstream_read_len_append(stream, line, i + 1);
230 i++;
231 }
232 if (mailstream_read_len_append(stream, line,
233 stream->read_buffer_len) == NULL)
234 return NULL;
235 if (end_of_multiline(line->str, line->len))
236 return line->str;
237 }
238 else
239 if (mailstream_feed_read_buffer(stream) == -1)
240 return NULL;
241 }
242 while (1);
243
244 return line->str;
245}
246#endif
247
248
249
250static ssize_t send_data_line(mailstream * s, const char * line, size_t length)
251{
252 int fix_eol;
253 const char * start;
254 size_t count;
255
256 start = line;
257
258 fix_eol = 0;
259 count = 0;
260
261 while (1) {
262 if (length == 0)
263 break;
264
265 if (* line == '\r') {
266 line ++;
267
268 count ++;
269 length --;
270
271 if (* line == '\n') {
272 line ++;
273
274 count ++;
275 length --;
276
277 break;
278 }
279 }
280
281 if (* line == '\n') {
282 line ++;
283
284 count ++;
285 length --;
286
287 fix_eol = 1;
288 break;
289 }
290
291 line ++;
292 length --;
293 count ++;
294 }
295
296 if (start[0] == '.')
297 if (mailstream_write(s, ".", 1) == -1)
298 goto err;
299
300 if (fix_eol) {
301 if (mailstream_write(s, start, count - 1) == -1)
302 goto err;
303 if (mailstream_write(s, "\r\n", 2) == -1)
304 goto err;
305 }
306 else {
307 if (mailstream_write(s, start, count) == -1)
308 goto err;
309 }
310
311
312#if 0
313 while (* line != '\n') {
314 if (* line == '\r')
315 pos = line;
316 if (* line == '\0')
317 return line;
318 if (mailstream_write(s, line, 1) == -1)
319 goto err;
320 line ++;
321 }
322 if (pos + 1 == line) {
323 if (mailstream_write(s, line, 1) == -1)
324 goto err;
325 }
326 else {
327 if (mailstream_write(s, "\r\n", 2) == -1)
328 goto err;
329 }
330 line ++;
331#endif
332
333 return count;
334
335 err:
336 return -1;
337}
338
339int mailstream_send_data(mailstream * s, const char * message,
340 size_t size,
341 size_t progr_rate,
342 progress_function * progr_fun)
343{
344 const char * current;
345 size_t count;
346 size_t last;
347 size_t remaining;
348
349 count = 0;
350 last = 0;
351
352 current = message;
353 remaining = size;
354
355 while (remaining > 0) {
356 ssize_t length;
357
358 length = send_data_line(s, current, remaining);
359 if (length < 0)
360 goto err;
361
362 current += length;
363
364 count += length;
365 if ((progr_rate != 0) && (progr_fun != NULL))
366 if (count - last >= progr_rate) {
367 (* progr_fun)(count, size);
368 last = count;
369 }
370
371 remaining -= length;
372 }
373 if (mailstream_write(s, "\r\n.\r\n", 5) == -1)
374 goto err;
375
376 if (mailstream_flush(s) == -1)
377 goto err;
378
379 return 0;
380
381 err:
382 return -1;
383}
diff --git a/kmicromail/libetpan/tools/mailstream_helper.h b/kmicromail/libetpan/tools/mailstream_helper.h
new file mode 100644
index 0000000..d030b1d
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mailstream_helper.h
@@ -0,0 +1,70 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSTREAM_HELPER_H
37
38#define MAILSTREAM_HELPER_H
39
40#include <libetpan/mmapstring.h>
41#include <libetpan/mailstream.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47char * mailstream_read_line(mailstream * stream, MMAPString * line);
48
49char * mailstream_read_line_append(mailstream * stream, MMAPString * line);
50
51char * mailstream_read_line_remove_eol(mailstream * stream, MMAPString * line);
52
53char * mailstream_read_multiline(mailstream * s, size_t size,
54 MMAPString * stream_buffer,
55 MMAPString * multiline_buffer,
56 size_t progr_rate,
57 progress_function * progr_fun);
58
59int mailstream_is_end_multiline(const char * line);
60
61int mailstream_send_data(mailstream * s, const char * message,
62 size_t size,
63 size_t progr_rate,
64 progress_function * progr_fun);
65
66#ifdef __cplusplus
67}
68#endif
69
70#endif
diff --git a/kmicromail/libetpan/tools/mailstream_low.c b/kmicromail/libetpan/tools/mailstream_low.c
new file mode 100644
index 0000000..34c96f1
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mailstream_low.c
@@ -0,0 +1,90 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailstream_low.h"
37#include <stdlib.h>
38
39/* general functions */
40
41mailstream_low * mailstream_low_new(void * data,
42 mailstream_low_driver * driver)
43{
44 mailstream_low * s;
45
46 s = malloc(sizeof(* s));
47 if (s == NULL)
48 return NULL;
49
50 s->data = data;
51 s->driver = driver;
52
53 return s;
54}
55
56int mailstream_low_close(mailstream_low * s)
57{
58 if (s == NULL)
59 return -1;
60 s->driver->mailstream_close(s);
61
62 return 0;
63}
64
65int mailstream_low_get_fd(mailstream_low * s)
66{
67 if (s == NULL)
68 return -1;
69 return s->driver->mailstream_get_fd(s);
70}
71
72void mailstream_low_free(mailstream_low * s)
73{
74 s->driver->mailstream_free(s);
75}
76
77ssize_t mailstream_low_read(mailstream_low * s, void * buf, size_t count)
78{
79 if (s == NULL)
80 return -1;
81 return s->driver->mailstream_read(s, buf, count);
82}
83
84ssize_t mailstream_low_write(mailstream_low * s,
85 const void * buf, size_t count)
86{
87 if (s == NULL)
88 return -1;
89 return s->driver->mailstream_write(s, buf, count);
90}
diff --git a/kmicromail/libetpan/tools/mailstream_low.h b/kmicromail/libetpan/tools/mailstream_low.h
new file mode 100644
index 0000000..fb8914c
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mailstream_low.h
@@ -0,0 +1,62 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSTREAM_LOW_H
37
38#define MAILSTREAM_LOW_H
39
40#include <sys/types.h>
41#include <libetpan/mailstream_types.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47/* general functions */
48
49mailstream_low * mailstream_low_new(void * data,
50 mailstream_low_driver * driver);
51ssize_t mailstream_low_write(mailstream_low * s,
52 const void * buf, size_t count);
53ssize_t mailstream_low_read(mailstream_low * s, void * buf, size_t count);
54int mailstream_low_close(mailstream_low * s);
55int mailstream_low_get_fd(mailstream_low * s);
56void mailstream_low_free(mailstream_low * s);
57
58#ifdef __cplusplus
59}
60#endif
61
62#endif
diff --git a/kmicromail/libetpan/tools/mailstream_socket.c b/kmicromail/libetpan/tools/mailstream_socket.c
new file mode 100644
index 0000000..29e50e1
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mailstream_socket.c
@@ -0,0 +1,239 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mailstream_socket.h"
37#include <unistd.h>
38#include <stdlib.h>
39#include <fcntl.h>
40
41/*
42 these 3 headers MUST be included before <sys/select.h>
43 to insure compatibility with Mac OS X (this is true for 10.2)
44*/
45#include <sys/time.h>
46#include <sys/socket.h>
47#include <sys/types.h>
48#include <unistd.h>
49#include <sys/select.h>
50
51/* mailstream_low, socket */
52
53static int mailstream_low_socket_close(mailstream_low * s);
54static ssize_t mailstream_low_socket_read(mailstream_low * s,
55 void * buf, size_t count);
56static ssize_t mailstream_low_socket_write(mailstream_low * s,
57 const void * buf, size_t count);
58static void mailstream_low_socket_free(mailstream_low * s);
59static int mailstream_low_socket_get_fd(mailstream_low * s);
60
61static mailstream_low_driver local_mailstream_socket_driver = {
62 mailstream_read: mailstream_low_socket_read,
63 mailstream_write: mailstream_low_socket_write,
64 mailstream_close: mailstream_low_socket_close,
65 mailstream_free: mailstream_low_socket_free,
66 mailstream_get_fd: mailstream_low_socket_get_fd,
67};
68
69mailstream_low_driver * mailstream_socket_driver =
70&local_mailstream_socket_driver;
71
72/* file descriptor must be given in (default) blocking-mode */
73
74static struct mailstream_socket_data * socket_data_new(int fd)
75{
76 struct mailstream_socket_data * socket_data;
77
78 socket_data = malloc(sizeof(* socket_data));
79 if (socket_data == NULL)
80 goto err;
81
82 socket_data->fd = fd;
83
84 return socket_data;
85
86 err:
87 return NULL;
88}
89
90static void socket_data_free(struct mailstream_socket_data * socket_data)
91{
92 free(socket_data);
93}
94
95static void socket_data_close(struct mailstream_socket_data * socket_data)
96{
97 close(socket_data->fd);
98 socket_data->fd = -1;
99}
100
101mailstream_low * mailstream_low_socket_open(int fd)
102{
103 mailstream_low * s;
104 struct mailstream_socket_data * socket_data;
105
106 socket_data = socket_data_new(fd);
107 if (socket_data == NULL)
108 goto err;
109
110 s = mailstream_low_new(socket_data, mailstream_socket_driver);
111 if (s == NULL)
112 goto free_socket_data;
113
114 return s;
115
116 free_socket_data:
117 socket_data_free(socket_data);
118 err:
119 return NULL;
120}
121
122static int mailstream_low_socket_close(mailstream_low * s)
123{
124 struct mailstream_socket_data * socket_data;
125
126 socket_data = (struct mailstream_socket_data *) s->data;
127 socket_data_close(socket_data);
128
129 return 0;
130}
131
132static void mailstream_low_socket_free(mailstream_low * s)
133{
134 struct mailstream_socket_data * socket_data;
135
136 socket_data = (struct mailstream_socket_data *) s->data;
137 socket_data_free(socket_data);
138 s->data = NULL;
139
140 free(s);
141}
142
143static int mailstream_low_socket_get_fd(mailstream_low * s)
144{
145 struct mailstream_socket_data * socket_data;
146
147 socket_data = (struct mailstream_socket_data *) s->data;
148 return socket_data->fd;
149}
150
151
152static ssize_t mailstream_low_socket_read(mailstream_low * s,
153 void * buf, size_t count)
154{
155 struct mailstream_socket_data * socket_data;
156
157 socket_data = (struct mailstream_socket_data *) s->data;
158
159 /* timeout */
160 {
161 fd_set fds_read;
162 fd_set fds_excp;
163 struct timeval timeout;
164 int r;
165
166 timeout = mailstream_network_delay;
167
168 FD_ZERO(&fds_read);
169 FD_SET(socket_data->fd, &fds_read);
170 FD_ZERO(&fds_excp);
171 FD_SET(socket_data->fd, &fds_excp);
172 r = select(socket_data->fd + 1, &fds_read, NULL, &fds_excp, &timeout);
173 if (r == 0)
174 return -1;
175 if (FD_ISSET(socket_data->fd, &fds_excp))
176 return -1;
177 if (!FD_ISSET(socket_data->fd, &fds_read))
178 return 0;
179 }
180 return recv(socket_data->fd,buf,count,MSG_NOSIGNAL);
181 //return read(socket_data->fd, buf, count);
182}
183
184static ssize_t mailstream_low_socket_write(mailstream_low * s,
185 const void * buf, size_t count)
186{
187 struct mailstream_socket_data * socket_data;
188
189 socket_data = (struct mailstream_socket_data *) s->data;
190 /* timeout */
191 {
192 fd_set fds_write;
193 fd_set fds_excp;
194 struct timeval timeout;
195 int r;
196
197 timeout = mailstream_network_delay;
198
199 FD_ZERO(&fds_write);
200 FD_SET(socket_data->fd, &fds_write);
201 FD_ZERO(&fds_excp);
202 FD_SET(socket_data->fd, &fds_excp);
203 r = select(socket_data->fd + 1, NULL, &fds_write, &fds_excp, &timeout);
204 if (r == 0)
205 return -1;
206 if (FD_ISSET(socket_data->fd, &fds_excp))
207 return -1;
208 if (!FD_ISSET(socket_data->fd, &fds_write))
209 return 0;
210 }
211
212 return send(socket_data->fd,buf,count,MSG_NOSIGNAL);
213 //return write(socket_data->fd, buf, count);
214}
215
216
217/* mailstream */
218
219mailstream * mailstream_socket_open(int fd)
220{
221 mailstream_low * low;
222 mailstream * s;
223
224 low = mailstream_low_socket_open(fd);
225 if (low == NULL)
226 goto err;
227
228 s = mailstream_new(low, 8192);
229 if (s == NULL)
230 goto free_low;
231
232 return s;
233
234 free_low:
235 mailstream_low_close(low);
236 err:
237 return NULL;
238}
239
diff --git a/kmicromail/libetpan/tools/mailstream_socket.h b/kmicromail/libetpan/tools/mailstream_socket.h
new file mode 100644
index 0000000..6a26e33
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mailstream_socket.h
@@ -0,0 +1,61 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSTREAM_SOCKET_H
37
38#define MAILSTREAM_SOCKET_H
39
40#include <libetpan/mailstream.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/* socket */
47
48extern mailstream_low_driver * mailstream_socket_driver;
49
50mailstream_low * mailstream_low_socket_open(int fd);
51mailstream * mailstream_socket_open(int fd);
52
53struct mailstream_socket_data {
54 int fd;
55};
56
57#ifdef __cplusplus
58}
59#endif
60
61#endif
diff --git a/kmicromail/libetpan/tools/mailstream_ssl.c b/kmicromail/libetpan/tools/mailstream_ssl.c
new file mode 100644
index 0000000..9f5008d
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mailstream_ssl.c
@@ -0,0 +1,312 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36/*
37 NOTE :
38
39 The user has to call himself SSL_library_init() if he wants to
40 use SSL.
41*/
42
43#include "mailstream_ssl.h"
44#include <unistd.h>
45#include <fcntl.h>
46
47#ifndef CONFIG_H
48#define CONFIG_H
49#include "config.h"
50#endif
51
52/*
53 these 3 headers MUST be included before <sys/select.h>
54 to insure compatibility with Mac OS X (this is true for 10.2)
55*/
56#include <sys/time.h>
57#include <sys/types.h>
58#include <unistd.h>
59#include <sys/select.h>
60
61/* mailstream_low, ssl */
62
63#ifdef USE_SSL
64#include <openssl/ssl.h>
65#include <pthread.h>
66#endif
67
68#ifdef USE_SSL
69struct mailstream_ssl_data {
70 int fd;
71 SSL * ssl_conn;
72 SSL_CTX * ssl_ctx;
73};
74#endif
75
76#ifdef USE_SSL
77static pthread_mutex_t ssl_lock = PTHREAD_MUTEX_INITIALIZER;
78static int ssl_init_done = 0;
79#endif
80
81#ifdef USE_SSL
82static int mailstream_low_ssl_close(mailstream_low * s);
83static ssize_t mailstream_low_ssl_read(mailstream_low * s,
84 void * buf, size_t count);
85static ssize_t mailstream_low_ssl_write(mailstream_low * s,
86 const void * buf, size_t count);
87static void mailstream_low_ssl_free(mailstream_low * s);
88static int mailstream_low_ssl_get_fd(mailstream_low * s);
89
90static mailstream_low_driver local_mailstream_ssl_driver = {
91 mailstream_read: mailstream_low_ssl_read,
92 mailstream_write: mailstream_low_ssl_write,
93 mailstream_close: mailstream_low_ssl_close,
94 mailstream_free: mailstream_low_ssl_free,
95 mailstream_get_fd: mailstream_low_ssl_get_fd,
96};
97
98mailstream_low_driver * mailstream_ssl_driver = &local_mailstream_ssl_driver;
99#endif
100
101/* file descriptor must be given in (default) blocking-mode */
102
103#ifdef USE_SSL
104static struct mailstream_ssl_data * ssl_data_new(int fd)
105{
106 struct mailstream_ssl_data * ssl_data;
107 SSL * ssl_conn;
108 int r;
109 SSL_CTX * tmp_ctx;
110 int fd_flags;
111 int old_fd_flags;
112
113 pthread_mutex_lock(&ssl_lock);
114 if (!ssl_init_done) {
115 SSL_library_init();
116 ssl_init_done = 1;
117 }
118 pthread_mutex_unlock(&ssl_lock);
119
120 tmp_ctx = SSL_CTX_new(TLSv1_client_method());
121 if (tmp_ctx == NULL)
122 goto err;
123
124 ssl_conn = (SSL *) SSL_new(tmp_ctx);
125 if (ssl_conn == NULL)
126 goto free_ctx;
127
128 if (SSL_set_fd(ssl_conn, fd) == 0)
129 goto free_ssl_conn;
130
131 SSL_set_read_ahead(ssl_conn, 1);
132
133 r = SSL_connect(ssl_conn);
134 if (r <= 0)
135 goto free_ssl_conn;
136
137 fd_flags = fcntl(fd, F_GETFL, 0);
138 old_fd_flags = fd_flags;
139 fd_flags |= O_NDELAY;
140 r = fcntl(fd, F_SETFL, fd_flags);
141 if (r < 0)
142 goto free_ssl_conn;
143
144 ssl_data = malloc(sizeof(* ssl_data));
145 if (ssl_data == NULL)
146 goto reset_fd_flags;
147
148 ssl_data->fd = fd;
149 ssl_data->ssl_conn = ssl_conn;
150 ssl_data->ssl_ctx = tmp_ctx;
151
152 return ssl_data;
153
154 reset_fd_flags:
155 fcntl(fd, F_SETFL, old_fd_flags);
156 free_ctx:
157 SSL_CTX_free(tmp_ctx);
158 free_ssl_conn:
159 SSL_free(ssl_conn);
160 err:
161 return NULL;
162}
163
164static void ssl_data_free(struct mailstream_ssl_data * ssl_data)
165{
166 free(ssl_data);
167}
168
169static void ssl_data_close(struct mailstream_ssl_data * ssl_data)
170{
171 SSL_free(ssl_data->ssl_conn);
172 ssl_data->ssl_conn = NULL;
173 SSL_CTX_free(ssl_data->ssl_ctx);
174 ssl_data->ssl_ctx = NULL;
175 close(ssl_data->fd);
176 ssl_data->fd = -1;
177}
178#endif
179
180mailstream_low * mailstream_low_ssl_open(int fd)
181{
182#ifdef USE_SSL
183 mailstream_low * s;
184 struct mailstream_ssl_data * ssl_data;
185
186 ssl_data = ssl_data_new(fd);
187 if (ssl_data == NULL)
188 goto err;
189
190 s = mailstream_low_new(ssl_data, mailstream_ssl_driver);
191 if (s == NULL)
192 goto free_ssl_data;
193
194 return s;
195
196 free_ssl_data:
197 ssl_data_free(ssl_data);
198 err:
199 return NULL;
200#else
201 return NULL;
202#endif
203}
204
205#ifdef USE_SSL
206static int mailstream_low_ssl_close(mailstream_low * s)
207{
208 struct mailstream_ssl_data * ssl_data;
209
210 ssl_data = (struct mailstream_ssl_data *) s->data;
211 ssl_data_close(ssl_data);
212
213 return 0;
214}
215
216static void mailstream_low_ssl_free(mailstream_low * s)
217{
218 struct mailstream_ssl_data * ssl_data;
219
220 ssl_data = (struct mailstream_ssl_data *) s->data;
221 ssl_data_free(ssl_data);
222 s->data = NULL;
223
224 free(s);
225}
226
227static int mailstream_low_ssl_get_fd(mailstream_low * s)
228{
229 struct mailstream_ssl_data * ssl_data;
230
231 ssl_data = (struct mailstream_ssl_data *) s->data;
232 return ssl_data->fd;
233}
234
235static ssize_t mailstream_low_ssl_read(mailstream_low * s,
236 void * buf, size_t count)
237{
238 struct mailstream_ssl_data * ssl_data;
239 int r;
240
241 ssl_data = (struct mailstream_ssl_data *) s->data;
242
243 while (1) {
244 int ssl_r;
245 fd_set fds_read;
246 struct timeval timeout;
247
248 r = SSL_read(ssl_data->ssl_conn, buf, count);
249 if (r > 0)
250 return r;
251
252 ssl_r = SSL_get_error(ssl_data->ssl_conn, r);
253 switch (ssl_r) {
254 case SSL_ERROR_NONE:
255 return r;
256
257 case SSL_ERROR_ZERO_RETURN:
258 return r;
259
260 case SSL_ERROR_WANT_READ:
261 timeout = mailstream_network_delay;
262
263 FD_ZERO(&fds_read);
264 FD_SET(ssl_data->fd, &fds_read);
265 r = select(ssl_data->fd + 1, &fds_read, NULL, NULL, &timeout);
266 if (r == 0)
267 return -1;
268 break;
269
270 default:
271 return r;
272 }
273 }
274}
275
276static ssize_t mailstream_low_ssl_write(mailstream_low * s,
277 const void * buf, size_t count)
278{
279 struct mailstream_ssl_data * ssl_data;
280
281 ssl_data = (struct mailstream_ssl_data *) s->data;
282 return SSL_write(ssl_data->ssl_conn, buf, count);
283}
284#endif
285
286/* mailstream */
287
288mailstream * mailstream_ssl_open(int fd)
289{
290#ifdef USE_SSL
291 mailstream_low * low;
292 mailstream * s;
293
294 low = mailstream_low_ssl_open(fd);
295 if (low == NULL)
296 goto err;
297
298 s = mailstream_new(low, 8192);
299 if (s == NULL)
300 goto free_low;
301
302 return s;
303
304 free_low:
305 mailstream_low_close(low);
306 err:
307 return NULL;
308#else
309 return NULL;
310#endif
311}
312
diff --git a/kmicromail/libetpan/tools/mailstream_ssl.h b/kmicromail/libetpan/tools/mailstream_ssl.h
new file mode 100644
index 0000000..a37b3d4
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mailstream_ssl.h
@@ -0,0 +1,59 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSTREAM_SSL_H
37
38#define MAILSTREAM_SSL_H
39
40#include <libetpan/mailstream.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/* socket */
47
48#ifdef USE_SSL
49extern mailstream_low_driver * mailstream_ssl_driver;
50#endif
51
52mailstream_low * mailstream_low_ssl_open(int fd);
53mailstream * mailstream_ssl_open(int fd);
54
55#ifdef __cplusplus
56}
57#endif
58
59#endif
diff --git a/kmicromail/libetpan/tools/mailstream_types.h b/kmicromail/libetpan/tools/mailstream_types.h
new file mode 100644
index 0000000..2165149
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mailstream_types.h
@@ -0,0 +1,87 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAILSTREAM_TYPES_H
37
38#define MAILSTREAM_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#define LIBETPAN_MAILSTREAM_DEBUG
45
46struct _mailstream;
47
48typedef struct _mailstream mailstream;
49
50struct _mailstream_low;
51
52typedef struct _mailstream_low mailstream_low;
53
54struct _mailstream {
55 size_t buffer_max_size;
56
57 char * write_buffer;
58 size_t write_buffer_len;
59
60 char * read_buffer;
61 size_t read_buffer_len;
62
63 mailstream_low * low;
64};
65
66struct mailstream_low_driver {
67 ssize_t (* mailstream_read)(mailstream_low *, void *, size_t);
68 ssize_t (* mailstream_write)(mailstream_low *, const void *, size_t);
69 int (* mailstream_close)(mailstream_low *);
70 int (* mailstream_get_fd)(mailstream_low *);
71 void (* mailstream_free)(mailstream_low *);
72};
73
74typedef struct mailstream_low_driver mailstream_low_driver;
75
76struct _mailstream_low {
77 void * data;
78 mailstream_low_driver * driver;
79};
80
81typedef void progress_function(size_t current, size_t maximum);
82
83#ifdef __cplusplus
84}
85#endif
86
87#endif
diff --git a/kmicromail/libetpan/tools/mapping.c b/kmicromail/libetpan/tools/mapping.c
new file mode 100644
index 0000000..426a03c
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mapping.c
@@ -0,0 +1,67 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mapping.h"
37
38#include <unistd.h>
39#include <sys/mman.h>
40
41int get_mapping(size_t length, int prot, int flags,
42 int fd, off_t offset,
43 void ** presult, void ** pmapping, size_t * pmapping_size)
44{
45 void * mapping;
46 size_t mapping_size;
47 void * result;
48 size_t page_size;
49 off_t delta;
50
51 page_size = getpagesize();
52 delta = offset % page_size;
53
54 mapping = mmap(NULL, length + offset, prot, flags, fd, offset - delta);
55 if (mapping == MAP_FAILED)
56 return -1;
57
58 result = ((char *) mapping) + delta;
59
60 mapping_size = length + offset;
61
62 * pmapping = mapping;
63 * pmapping_size = mapping_size;
64 * presult = result;
65
66 return 0;
67}
diff --git a/kmicromail/libetpan/tools/mapping.h b/kmicromail/libetpan/tools/mapping.h
new file mode 100644
index 0000000..8e72f98
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mapping.h
@@ -0,0 +1,54 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef MAPPING_H
37
38#define MAPPING_H
39
40#include <sys/types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46int get_mapping(size_t length, int prot, int flags,
47 int fd, off_t offset,
48 void ** presult, void ** pmapping, size_t * pmapping_size);
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/kmicromail/libetpan/tools/md5.c b/kmicromail/libetpan/tools/md5.c
new file mode 100644
index 0000000..50307e0
--- a/dev/null
+++ b/kmicromail/libetpan/tools/md5.c
@@ -0,0 +1,570 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
37*/
38
39/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
40rights reserved.
41
42License to copy and use this software is granted provided that it
43is identified as the "RSA Data Security, Inc. MD5 Message-Digest
44Algorithm" in all material mentioning or referencing this software
45or this function.
46
47License is also granted to make and use derivative works provided
48that such works are identified as "derived from the RSA Data
49Security, Inc. MD5 Message-Digest Algorithm" in all material
50mentioning or referencing the derived work.
51
52RSA Data Security, Inc. makes no representations concerning either
53the merchantability of this software or the suitability of this
54software for any particular purpose. It is provided "as is"
55without express or implied warranty of any kind.
56
57These notices must be retained in any copies of any part of this
58documentation and/or software.
59*/
60
61/* do i need all of this just for htonl()? damn. */
62#include <sys/types.h>
63#include <sys/param.h>
64#include <sys/socket.h>
65#include <netinet/in.h>
66
67#include "md5global.h"
68#include "md5.h"
69#include "hmac-md5.h"
70
71/* Constants for MD5Transform routine.
72*/
73
74#define S11 7
75#define S12 12
76#define S13 17
77#define S14 22
78#define S21 5
79#define S22 9
80#define S23 14
81#define S24 20
82#define S31 4
83#define S32 11
84#define S33 16
85#define S34 23
86#define S41 6
87#define S42 10
88#define S43 15
89#define S44 21
90
91static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
92static void Encode PROTO_LIST
93 ((unsigned char *, UINT4 *, unsigned int));
94static void Decode PROTO_LIST
95 ((UINT4 *, unsigned char *, unsigned int));
96static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
97static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
98
99static unsigned char PADDING[64] = {
100 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
102};
103
104/* F, G, H and I are basic MD5 functions.
105
106 */
107#ifdef I
108/* This might be defined via NANA */
109#undef I
110#endif
111
112#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
113#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
114#define H(x, y, z) ((x) ^ (y) ^ (z))
115#define I(x, y, z) ((y) ^ ((x) | (~z)))
116
117/* ROTATE_LEFT rotates x left n bits.
118
119 */
120
121#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
122
123/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
124Rotation is separate from addition to prevent recomputation.
125*/
126
127#define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
128#define GG(a, b, c, d, x, s, ac) { (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
129#define HH(a, b, c, d, x, s, ac) { (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
130#define II(a, b, c, d, x, s, ac) { (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
131
132/* MD5 initialization. Begins an MD5 operation, writing a new context.
133*/
134
135void MD5Init (context)
136MD5_CTX *context; /* context */
137{
138 context->count[0] = context->count[1] = 0;
139
140 /* Load magic initialization constants.
141
142*/
143 context->state[0] = 0x67452301;
144 context->state[1] = 0xefcdab89;
145 context->state[2] = 0x98badcfe;
146 context->state[3] = 0x10325476;
147}
148
149/* MD5 block update operation. Continues an MD5 message-digest
150 operation, processing another message block, and updating the context.
151*/
152
153void MD5Update (context, input, inputLen)
154MD5_CTX *context; /* context */
155unsigned char *input; /* input block */
156unsigned int inputLen; /* length of input block */
157{
158 unsigned int i, index, partLen;
159
160 /* Compute number of bytes mod 64 */
161 index = (unsigned int)((context->count[0] >> 3) & 0x3F);
162
163 /* Update number of bits */
164 if ((context->count[0] += ((UINT4)inputLen << 3))
165 < ((UINT4)inputLen << 3))
166 context->count[1]++;
167 context->count[1] += ((UINT4)inputLen >> 29);
168
169 partLen = 64 - index;
170
171 /* Transform as many times as possible.
172
173*/
174 if (inputLen >= partLen) {
175 MD5_memcpy
176 ((POINTER)&context->buffer[index], (POINTER)input, partLen); MD5Transform
177 (context->state, context->buffer);
178
179 for (i = partLen; i + 63 < inputLen; i += 64)
180 MD5Transform (context->state, &input[i]);
181
182 index = 0;
183 }
184 else
185 i = 0;
186
187 /* Buffer remaining input */
188 MD5_memcpy
189 ((POINTER)&context->buffer[index], (POINTER)&input[i],
190 inputLen-i);
191
192}
193
194/* MD5 finalization. Ends an MD5 message-digest operation, writing the
195 the message digest and zeroizing the context.
196
197 */
198
199void MD5Final (digest, context)
200unsigned char digest[16]; /* message digest */
201MD5_CTX *context; /* context */
202{
203 unsigned char bits[8];
204 unsigned int index, padLen;
205
206 /* Save number of bits */
207 Encode (bits, context->count, 8);
208
209 /* Pad out to 56 mod 64.
210
211*/
212 index = (unsigned int)((context->count[0] >> 3) & 0x3f);
213 padLen = (index < 56) ? (56 - index) : (120 - index);
214 MD5Update (context, PADDING, padLen);
215
216 /* Append length (before padding) */
217 MD5Update (context, bits, 8);
218
219 /* Store state in digest */
220 Encode (digest, context->state, 16);
221
222 /* Zeroize sensitive information.
223
224*/
225 MD5_memset ((POINTER)context, 0, sizeof (*context));
226}
227
228/* MD5 basic transformation. Transforms state based on block.
229
230 */
231
232static void MD5Transform (state, block)
233UINT4 state[4];
234unsigned char block[64];
235{
236 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
237
238 Decode (x, block, 64);
239
240 /* Round 1 */
241 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
242 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
243 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
244 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
245 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
246 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
247 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
248 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
249 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
250 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
251 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
252 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
253 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
254 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
255 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
256 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
257
258 /* Round 2 */
259 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
260 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
261 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
262 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
263 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
264 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
265 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
266 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
267 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
268 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
269 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
270 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
271 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
272 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
273 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
274 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
275
276 /* Round 3 */
277 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
278 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
279 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
280 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
281 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
282 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
283 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
284 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
285 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
286 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
287 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
288 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
289 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
290 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
291 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
292 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
293
294 /* Round 4 */
295 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
296 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
297 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
298 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
299 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
300 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
301 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
302 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
303 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
304 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
305 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
306 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
307 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
308 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
309 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
310 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
311
312 state[0] += a;
313 state[1] += b;
314 state[2] += c;
315 state[3] += d;
316
317 /* Zeroize sensitive information.
318 */
319 MD5_memset ((POINTER)x, 0, sizeof (x));
320}
321
322/* Encodes input (UINT4) into output (unsigned char). Assumes len is
323 a multiple of 4.
324
325 */
326
327static void Encode (output, input, len)
328unsigned char *output;
329UINT4 *input;
330unsigned int len;
331{
332 unsigned int i, j;
333
334 for (i = 0, j = 0; j < len; i++, j += 4) {
335 output[j] = (unsigned char)(input[i] & 0xff);
336 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
337 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
338 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
339 }
340}
341
342/* Decodes input (unsigned char) into output (UINT4). Assumes len is
343 a multiple of 4.
344
345 */
346
347static void Decode (output, input, len)
348UINT4 *output;
349unsigned char *input;
350unsigned int len;
351{
352 unsigned int i, j;
353
354 for (i = 0, j = 0; j < len; i++, j += 4)
355 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16)
356 | (((UINT4)input[j+3]) << 24);
357}
358
359/* Note: Replace "for loop" with standard memcpy if possible.
360
361 */
362
363static void MD5_memcpy (output, input, len)
364POINTER output;
365POINTER input;
366unsigned int len;
367{
368 unsigned int i;
369
370 for (i = 0; i < len; i++)
371 output[i] = input[i];
372}
373
374/* Note: Replace "for loop" with standard memset if possible.
375*/
376
377static void MD5_memset (output, value, len)
378POINTER output;
379int value;
380unsigned int len;
381{
382 unsigned int i;
383
384 for (i = 0; i < len; i++)
385 ((char *)output)[i] = (char)value;
386}
387
388void hmac_md5_init(HMAC_MD5_CTX *hmac,
389 const unsigned char *key,
390 int key_len)
391{
392 unsigned char k_ipad[65]; /* inner padding -
393 * key XORd with ipad
394 */
395 unsigned char k_opad[65]; /* outer padding -
396 * key XORd with opad
397 */
398 unsigned char tk[16];
399 int i;
400 /* if key is longer than 64 bytes reset it to key=MD5(key) */
401 if (key_len > 64) {
402
403 MD5_CTX tctx;
404
405 MD5Init(&tctx);
406 MD5Update(&tctx, key, key_len);
407 MD5Final(tk, &tctx);
408
409 key = tk;
410 key_len = 16;
411 }
412
413 /*
414 * the HMAC_MD5 transform looks like:
415 *
416 * MD5(K XOR opad, MD5(K XOR ipad, text))
417 *
418 * where K is an n byte key
419 * ipad is the byte 0x36 repeated 64 times
420 * opad is the byte 0x5c repeated 64 times
421 * and text is the data being protected
422 */
423
424 /* start out by storing key in pads */
425 MD5_memset(k_ipad, '\0', sizeof k_ipad);
426 MD5_memset(k_opad, '\0', sizeof k_opad);
427 MD5_memcpy( k_ipad, key, key_len);
428 MD5_memcpy( k_opad, key, key_len);
429
430 /* XOR key with ipad and opad values */
431 for (i=0; i<64; i++) {
432 k_ipad[i] ^= 0x36;
433 k_opad[i] ^= 0x5c;
434 }
435
436 MD5Init(&hmac->ictx); /* init inner context */
437 MD5Update(&hmac->ictx, k_ipad, 64); /* apply inner pad */
438
439 MD5Init(&hmac->octx); /* init outer context */
440 MD5Update(&hmac->octx, k_opad, 64); /* apply outer pad */
441
442 /* scrub the pads and key context (if used) */
443 MD5_memset(&k_ipad, 0, sizeof(k_ipad));
444 MD5_memset(&k_opad, 0, sizeof(k_opad));
445 MD5_memset(&tk, 0, sizeof(tk));
446
447 /* and we're done. */
448}
449
450/* The precalc and import routines here rely on the fact that we pad
451 * the key out to 64 bytes and use that to initialize the md5
452 * contexts, and that updating an md5 context with 64 bytes of data
453 * leaves nothing left over; all of the interesting state is contained
454 * in the state field, and none of it is left over in the count and
455 * buffer fields. So all we have to do is save the state field; we
456 * can zero the others when we reload it. Which is why the decision
457 * was made to pad the key out to 64 bytes in the first place. */
458void hmac_md5_precalc(HMAC_MD5_STATE *state,
459 const unsigned char *key,
460 int key_len)
461{
462 HMAC_MD5_CTX hmac;
463 unsigned lupe;
464
465 hmac_md5_init(&hmac, key, key_len);
466 for (lupe = 0; lupe < 4; lupe++) {
467 state->istate[lupe] = htonl(hmac.ictx.state[lupe]);
468 state->ostate[lupe] = htonl(hmac.octx.state[lupe]);
469 }
470 MD5_memset(&hmac, 0, sizeof(hmac));
471}
472
473
474void hmac_md5_import(HMAC_MD5_CTX *hmac,
475 HMAC_MD5_STATE *state)
476{
477 unsigned lupe;
478 MD5_memset(hmac, 0, sizeof(HMAC_MD5_CTX));
479 for (lupe = 0; lupe < 4; lupe++) {
480 hmac->ictx.state[lupe] = ntohl(state->istate[lupe]);
481 hmac->octx.state[lupe] = ntohl(state->ostate[lupe]);
482 }
483 /* Init the counts to account for our having applied
484 * 64 bytes of key; this works out to 0x200 (64 << 3; see
485 * MD5Update above...) */
486 hmac->ictx.count[0] = hmac->octx.count[0] = 0x200;
487}
488
489void hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE],
490 HMAC_MD5_CTX *hmac)
491{
492 MD5Final(digest, &hmac->ictx); /* Finalize inner md5 */
493 MD5Update(&hmac->octx, digest, 16); /* Update outer ctx */
494 MD5Final(digest, &hmac->octx); /* Finalize outer md5 */
495}
496
497
498void hmac_md5(text, text_len, key, key_len, digest)
499const unsigned char* text; /* pointer to data stream */
500int text_len; /* length of data stream */
501const unsigned char* key; /* pointer to authentication key */
502int key_len; /* length of authentication key */
503unsigned char *digest; /* caller digest to be filled in */
504{
505 MD5_CTX context;
506
507 unsigned char k_ipad[65]; /* inner padding -
508 * key XORd with ipad
509 */
510 unsigned char k_opad[65]; /* outer padding -
511 * key XORd with opad
512 */
513 unsigned char tk[16];
514 int i;
515 /* if key is longer than 64 bytes reset it to key=MD5(key) */
516 if (key_len > 64) {
517
518 MD5_CTX tctx;
519
520 MD5Init(&tctx);
521 MD5Update(&tctx, key, key_len);
522 MD5Final(tk, &tctx);
523
524 key = tk;
525 key_len = 16;
526 }
527
528 /*
529 * the HMAC_MD5 transform looks like:
530 *
531 * MD5(K XOR opad, MD5(K XOR ipad, text))
532 *
533 * where K is an n byte key
534 * ipad is the byte 0x36 repeated 64 times
535 * opad is the byte 0x5c repeated 64 times
536 * and text is the data being protected
537 */
538
539 /* start out by storing key in pads */
540 MD5_memset(k_ipad, '\0', sizeof k_ipad);
541 MD5_memset(k_opad, '\0', sizeof k_opad);
542 MD5_memcpy( k_ipad, key, key_len);
543 MD5_memcpy( k_opad, key, key_len);
544
545 /* XOR key with ipad and opad values */
546 for (i=0; i<64; i++) {
547 k_ipad[i] ^= 0x36;
548 k_opad[i] ^= 0x5c;
549 }
550 /*
551 * perform inner MD5
552 */
553
554 MD5Init(&context); /* init context for 1st
555 * pass */
556 MD5Update(&context, k_ipad, 64); /* start with inner pad */
557 MD5Update(&context, text, text_len); /* then text of datagram */
558 MD5Final(digest, &context); /* finish up 1st pass */
559
560 /*
561 * perform outer MD5
562 */
563 MD5Init(&context); /* init context for 2nd
564 * pass */
565 MD5Update(&context, k_opad, 64); /* start with outer pad */
566 MD5Update(&context, digest, 16); /* then results of 1st
567 * hash */
568 MD5Final(digest, &context); /* finish up 2nd pass */
569
570}
diff --git a/kmicromail/libetpan/tools/md5.h b/kmicromail/libetpan/tools/md5.h
new file mode 100644
index 0000000..e62f157
--- a/dev/null
+++ b/kmicromail/libetpan/tools/md5.h
@@ -0,0 +1,88 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36/* MD5.H - header file for MD5C.C
37 */
38
39/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
40rights reserved.
41
42License to copy and use this software is granted provided that it
43is identified as the "RSA Data Security, Inc. MD5 Message-Digest
44Algorithm" in all material mentioning or referencing this software
45or this function.
46
47License is also granted to make and use derivative works provided
48that such works are identified as "derived from the RSA Data
49Security, Inc. MD5 Message-Digest Algorithm" in all material
50mentioning or referencing the derived work.
51
52RSA Data Security, Inc. makes no representations concerning either
53the merchantability of this software or the suitability of this
54software for any particular purpose. It is provided "as is"
55without express or implied warranty of any kind.
56These notices must be retained in any copies of any part of this
57documentation and/or software.
58 */
59
60#include "md5global.h"
61
62#ifndef MD5_H
63
64#define MD5_H
65
66#ifdef __cplusplus
67extern "C" {
68#endif
69
70/* MD5 context. */
71typedef struct {
72 UINT4 state[4]; /* state (ABCD) */
73 UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
74 unsigned char buffer[64]; /* input buffer */
75} MD5_CTX;
76
77void MD5Init PROTO_LIST ((MD5_CTX *));
78void MD5Update PROTO_LIST
79 ((MD5_CTX *, unsigned char *, unsigned int));
80void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
81
82void hmac_md5 PROTO_LIST ((unsigned char *, int, unsigned char *, int, caddr_t));
83
84#ifdef __cplusplus
85}
86#endif
87
88#endif
diff --git a/kmicromail/libetpan/tools/md5global.h b/kmicromail/libetpan/tools/md5global.h
new file mode 100644
index 0000000..9089c9a
--- a/dev/null
+++ b/kmicromail/libetpan/tools/md5global.h
@@ -0,0 +1,79 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36/* GLOBAL.H - RSAREF types and constants
37 */
38
39#ifndef MD5GLOBAL_H
40
41#define MD5GLOBAL_H
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47/* PROTOTYPES should be set to one if and only if the compiler supports
48 function argument prototyping.
49The following makes PROTOTYPES default to 0 if it has not already
50 been defined with C compiler flags.
51 */
52#ifndef PROTOTYPES
53#define PROTOTYPES 0
54#endif
55
56/* POINTER defines a generic pointer type */
57typedef unsigned char *POINTER;
58
59/* UINT2 defines a two byte word */
60typedef unsigned short int UINT2;
61
62/* UINT4 defines a four byte word */
63typedef unsigned long int UINT4;
64
65/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
66If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
67 returns an empty list.
68 */
69#if PROTOTYPES
70#define PROTO_LIST(list) list
71#else
72#define PROTO_LIST(list) ()
73#endif
74
75#ifdef __cplusplus
76}
77#endif
78
79#endif
diff --git a/kmicromail/libetpan/tools/mmapstring.c b/kmicromail/libetpan/tools/mmapstring.c
new file mode 100644
index 0000000..8c44842
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mmapstring.c
@@ -0,0 +1,526 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "mmapstring.h"
37
38#include "chash.h"
39
40#include <stdlib.h>
41#include <unistd.h>
42#include <sys/mman.h>
43#include <string.h>
44#include <pthread.h>
45
46#include "libetpan-config.h"
47
48#define MAX(a, b) ((a) > (b) ? (a) : (b))
49#define MIN(a, b) ((a) < (b) ? (a) : (b))
50
51#define MMAP_STRING_DEFAULT_CEIL (8 * 1024 * 1024)
52
53#define DEFAULT_TMP_PATH "/tmp"
54
55static char tmpdir[PATH_MAX] = DEFAULT_TMP_PATH;
56
57static size_t mmap_string_ceil = MMAP_STRING_DEFAULT_CEIL;
58
59/* MMAPString references */
60
61static pthread_mutex_t mmapstring_lock = PTHREAD_MUTEX_INITIALIZER;
62static chash * mmapstring_hashtable = NULL;
63
64static void mmapstring_hashtable_init()
65{
66 mmapstring_hashtable = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY);
67}
68
69void mmap_string_set_tmpdir(char * directory)
70{
71 strncpy(tmpdir, directory, PATH_MAX);
72 tmpdir[PATH_MAX - 1] = 0;
73}
74
75
76int mmap_string_ref(MMAPString * string)
77{
78 chash * ht;
79 int r;
80 chashdatum key;
81 chashdatum data;
82
83 pthread_mutex_lock(&mmapstring_lock);
84 if (mmapstring_hashtable == NULL) {
85 mmapstring_hashtable_init();
86 }
87 ht = mmapstring_hashtable;
88
89 if (ht == NULL) {
90 pthread_mutex_unlock(&mmapstring_lock);
91 return -1;
92 }
93
94 key.data = &string->str;
95 key.len = sizeof(string->str);
96 data.data = string;
97 data.len = 0;
98
99 r = chash_set(mmapstring_hashtable, &key, &data, NULL);
100 pthread_mutex_unlock(&mmapstring_lock);
101
102 if (r < 0)
103 return r;
104
105 return 0;
106}
107
108int mmap_string_unref(char * str)
109{
110 MMAPString * string;
111 chash * ht;
112 chashdatum key;
113 chashdatum data;
114 int r;
115
116 pthread_mutex_lock(&mmapstring_lock);
117 ht = mmapstring_hashtable;
118
119 if (ht == NULL) {
120 pthread_mutex_unlock(&mmapstring_lock);
121 return -1;
122 }
123
124 key.data = &str;
125 key.len = sizeof(str);
126
127 r = chash_get(ht, &key, &data);
128 if (r < 0)
129 string = NULL;
130 else
131 string = data.data;
132
133 if (string != NULL) {
134 chash_delete(ht, &key, NULL);
135 if (chash_count(ht) == 0) {
136 chash_free(ht);
137 mmapstring_hashtable = NULL;
138 }
139 }
140
141 pthread_mutex_unlock(&mmapstring_lock);
142
143 if (string != NULL) {
144 mmap_string_free(string);
145 return 0;
146 }
147 else
148 return -1;
149}
150
151
152
153/* MMAPString */
154
155#define MY_MAXSIZE ((size_t) -1)
156
157static inline size_t
158nearest_power (size_t base, size_t num)
159{
160 if (num > MY_MAXSIZE / 2) {
161 return MY_MAXSIZE;
162 }
163 else {
164 size_t n = base;
165
166 while (n < num)
167 n <<= 1;
168
169 return n;
170 }
171}
172
173void mmap_string_set_ceil(size_t ceil)
174{
175 mmap_string_ceil = ceil;
176}
177
178/* Strings.
179 */
180
181static MMAPString * mmap_string_realloc_file(MMAPString * string)
182{
183 char * data;
184
185 if (string->fd == -1) {
186 char tmpfilename[PATH_MAX];
187 int fd;
188
189 * tmpfilename = 0;
190 strcat(tmpfilename, tmpdir);
191 strcat(tmpfilename, "/libetpan-mmapstring-XXXXXX");
192
193 fd = mkstemp(tmpfilename);
194 if (fd == -1)
195 return NULL;
196
197 if (unlink(tmpfilename) == -1) {
198 close(fd);
199 return NULL;
200 }
201
202 if (ftruncate(fd, string->allocated_len) == -1) {
203 close(fd);
204 return NULL;
205 }
206
207 data = mmap(NULL, string->allocated_len, PROT_WRITE | PROT_READ,
208 MAP_SHARED, fd, 0);
209
210 if (data == MAP_FAILED) {
211 close(fd);
212 return NULL;
213 }
214
215 if (string->str != NULL)
216 memcpy(data, string->str, string->len + 1);
217
218 string->fd = fd;
219 string->mmapped_size = string->allocated_len;
220 free(string->str);
221 string->str = data;
222 }
223 else {
224 if (munmap(string->str, string->mmapped_size) == -1)
225 return NULL;
226
227 if (ftruncate(string->fd, string->allocated_len) == -1)
228 return NULL;
229
230 data = mmap(NULL, string->allocated_len, PROT_WRITE | PROT_READ,
231 MAP_SHARED, string->fd, 0);
232
233 if (data == MAP_FAILED)
234 return NULL;
235
236 string->mmapped_size = string->allocated_len;
237 string->str = data;
238 }
239
240 return string;
241}
242
243static MMAPString * mmap_string_realloc_memory(MMAPString * string)
244{
245 char * tmp;
246
247 tmp = realloc (string->str, string->allocated_len);
248
249 if (tmp == NULL)
250 string = NULL;
251 else
252 string->str = tmp;
253
254 return string;
255}
256
257static MMAPString *
258mmap_string_maybe_expand (MMAPString* string,
259 size_t len)
260{
261 if (string->len + len >= string->allocated_len)
262 {
263 size_t old_size;
264 MMAPString * newstring;
265
266 old_size = string->allocated_len;
267
268 string->allocated_len = nearest_power (1, string->len + len + 1);
269
270#ifndef MMAP_UNAVAILABLE
271 if (string->allocated_len > mmap_string_ceil)
272 newstring = mmap_string_realloc_file(string);
273 else {
274#endif
275 newstring = mmap_string_realloc_memory(string);
276#ifndef MMAP_UNAVAILABLE
277 if (newstring == NULL)
278 newstring = mmap_string_realloc_file(string);
279 }
280#endif
281
282 if (newstring == NULL)
283 string->allocated_len = old_size;
284 }
285
286 return string;
287}
288
289MMAPString*
290mmap_string_sized_new (size_t dfl_size)
291{
292 MMAPString *string;
293
294 string = malloc(sizeof(* string));
295 if (string == NULL)
296 return NULL;
297
298 string->allocated_len = 0;
299 string->len = 0;
300 string->str = NULL;
301 string->fd = -1;
302 string->mmapped_size = 0;
303
304 if (mmap_string_maybe_expand (string, MAX (dfl_size, 2)) == NULL)
305 return NULL;
306
307 string->str[0] = 0;
308
309 return string;
310}
311
312MMAPString*
313mmap_string_new (const char *init)
314{
315 MMAPString *string;
316
317 string = mmap_string_sized_new (init ? strlen (init) + 2 : 2);
318 if (string == NULL)
319 return NULL;
320
321 if (init)
322 mmap_string_append (string, init);
323
324 return string;
325}
326
327MMAPString*
328mmap_string_new_len (const char *init,
329 size_t len)
330{
331 MMAPString *string;
332
333 if (len <= 0)
334 return mmap_string_new (init);
335 else
336 {
337 string = mmap_string_sized_new (len);
338
339 if (init)
340 mmap_string_append_len (string, init, len);
341
342 return string;
343 }
344}
345
346void
347mmap_string_free (MMAPString *string)
348{
349 if (string == NULL)
350 return;
351
352 if (string->fd != -1) {
353 munmap(string->str, string->mmapped_size);
354 close(string->fd);
355 }
356 else {
357 free (string->str);
358 }
359 free(string);
360}
361
362MMAPString*
363mmap_string_assign (MMAPString *string,
364 const char *rval)
365{
366 mmap_string_truncate (string, 0);
367 if (mmap_string_append (string, rval) == NULL)
368 return NULL;
369
370 return string;
371}
372
373MMAPString*
374mmap_string_truncate (MMAPString *string,
375 size_t len)
376{
377 string->len = MIN (len, string->len);
378 string->str[string->len] = 0;
379
380 return string;
381}
382
383/**
384 * mmap_string_set_size:
385 * @string: a #MMAPString
386 * @len: the new length
387 *
388 * Sets the length of a #MMAPString. If the length is less than
389 * the current length, the string will be truncated. If the
390 * length is greater than the current length, the contents
391 * of the newly added area are undefined. (However, as
392 * always, string->str[string->len] will be a nul byte.)
393 *
394 * Return value: @string
395 **/
396MMAPString*
397mmap_string_set_size (MMAPString *string,
398 size_t len)
399{
400 if (len >= string->allocated_len)
401 if (mmap_string_maybe_expand (string, len - string->len) == NULL)
402 return NULL;
403
404 string->len = len;
405 string->str[len] = 0;
406
407 return string;
408}
409
410/*
411static int in_mapped_zone(MMAPString * string, char * val)
412{
413 return (val >= string->str) && (val < string->str + string->mmapped_size);
414}
415*/
416
417MMAPString*
418mmap_string_insert_len (MMAPString *string,
419 size_t pos,
420 const char *val,
421 size_t len)
422{
423 if (mmap_string_maybe_expand (string, len) == NULL)
424 return NULL;
425
426 if (pos < string->len)
427 memmove (string->str + pos + len, string->str + pos, string->len - pos);
428
429 /* insert the new string */
430 memmove (string->str + pos, val, len);
431
432 string->len += len;
433
434 string->str[string->len] = 0;
435
436 return string;
437}
438
439MMAPString*
440mmap_string_append (MMAPString *string,
441 const char *val)
442{
443 return mmap_string_insert_len (string, string->len, val, strlen(val));
444}
445
446MMAPString*
447 mmap_string_append_len (MMAPString *string,
448 const char *val,
449 size_t len)
450{
451 return mmap_string_insert_len (string, string->len, val, len);
452}
453
454MMAPString*
455mmap_string_append_c (MMAPString *string,
456 char c)
457{
458 return mmap_string_insert_c (string, string->len, c);
459}
460
461MMAPString*
462mmap_string_prepend (MMAPString *string,
463 const char *val)
464{
465 return mmap_string_insert_len (string, 0, val, strlen(val));
466}
467
468MMAPString*
469 mmap_string_prepend_len (MMAPString *string,
470 const char *val,
471 size_t len)
472{
473 return mmap_string_insert_len (string, 0, val, len);
474}
475
476MMAPString*
477mmap_string_prepend_c (MMAPString *string,
478 char c)
479{
480 return mmap_string_insert_c (string, 0, c);
481}
482
483MMAPString*
484mmap_string_insert (MMAPString *string,
485 size_t pos,
486 const char *val)
487{
488 return mmap_string_insert_len (string, pos, val, strlen(val));
489}
490
491MMAPString*
492mmap_string_insert_c (MMAPString *string,
493 size_t pos,
494 char c)
495{
496 if (mmap_string_maybe_expand (string, 1) == NULL)
497 return NULL;
498
499 /* If not just an append, move the old stuff */
500 if (pos < string->len)
501 memmove (string->str + pos + 1, string->str + pos, string->len - pos);
502
503 string->str[pos] = c;
504
505 string->len += 1;
506
507 string->str[string->len] = 0;
508
509 return string;
510}
511
512MMAPString*
513mmap_string_erase (MMAPString *string,
514 size_t pos,
515 size_t len)
516{
517 if ((pos + len) < string->len)
518 memmove (string->str + pos, string->str + pos + len,
519 string->len - (pos + len));
520
521 string->len -= len;
522
523 string->str[string->len] = 0;
524
525 return string;
526}
diff --git a/kmicromail/libetpan/tools/mmapstring.h b/kmicromail/libetpan/tools/mmapstring.h
new file mode 100644
index 0000000..6d7227d
--- a/dev/null
+++ b/kmicromail/libetpan/tools/mmapstring.h
@@ -0,0 +1,136 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#ifndef __MMAP_STRING_H__
37
38#define __MMAP_STRING_H__
39
40#include <sys/types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47#define TMPDIR "/tmp"
48*/
49
50typedef struct _MMAPString MMAPString;
51
52struct _MMAPString
53{
54 char * str;
55 size_t len;
56 size_t allocated_len;
57 int fd;
58 size_t mmapped_size;
59 /*
60 char * old_non_mmapped_str;
61 */
62};
63
64/* configure location of mmaped files */
65
66void mmap_string_set_tmpdir(char * directory);
67
68/* Strings
69 */
70
71MMAPString * mmap_string_new (const char * init);
72
73MMAPString * mmap_string_new_len (const char * init,
74 size_t len);
75
76MMAPString * mmap_string_sized_new (size_t dfl_size);
77
78void mmap_string_free (MMAPString * string);
79
80MMAPString * mmap_string_assign (MMAPString * string,
81 const char * rval);
82
83MMAPString * mmap_string_truncate (MMAPString *string,
84 size_t len);
85
86MMAPString * mmap_string_set_size (MMAPString * string,
87 size_t len);
88
89MMAPString * mmap_string_insert_len (MMAPString * string,
90 size_t pos,
91 const char * val,
92 size_t len);
93
94MMAPString * mmap_string_append (MMAPString * string,
95 const char * val);
96
97MMAPString * mmap_string_append_len (MMAPString * string,
98 const char * val,
99 size_t len);
100
101MMAPString * mmap_string_append_c (MMAPString * string,
102 char c);
103
104MMAPString * mmap_string_prepend (MMAPString * string,
105 const char * val);
106
107MMAPString * mmap_string_prepend_c (MMAPString * string,
108 char c);
109
110MMAPString * mmap_string_prepend_len (MMAPString * string,
111 const char * val,
112 size_t len);
113
114MMAPString * mmap_string_insert (MMAPString * string,
115 size_t pos,
116 const char * val);
117
118MMAPString * mmap_string_insert_c (MMAPString *string,
119 size_t pos,
120 char c);
121
122MMAPString * mmap_string_erase(MMAPString * string,
123 size_t pos,
124 size_t len);
125
126void mmap_string_set_ceil(size_t ceil);
127
128int mmap_string_ref(MMAPString * string);
129int mmap_string_unref(char * str);
130
131#ifdef __cplusplus
132}
133#endif
134
135
136#endif /* __MMAP_STRING_H__ */