TinyMail研究—Camellite的插件系统

TinyMail研究—Camel-lite的插件系统

             

转载时请注明出处和作者联系方式:http://blog.csdn.net/absurd

作者联系方式:李先静<xianjimli at hotmail dot com>

更新时间:2007-4-19

 

TinyMail是一套针对移动设备设计的邮件系统框架,为了达到最大的灵活性,它采用了很多设计模式和先进的编程技术,让框架的每一部分都可以定制和配置。TinyMail流行的趋势非常明显,Nokia770/800GPE Phone Edition等项目中都使用了它。因为我们也要开发邮件系统,所以花了几天时间去研究它的实现,这里记录一些研究笔记,供有兴趣的朋友参考。本文介绍一下Camel-lite的插件系统。

 

邮件的收/发协议有好几种,比如SMTPPOPIMAP等等,Tinymail并不依赖于特定的收/发协议,这些协议都是以插件的方式加入进来的,扩展和裁减都很方便。Tinymail把协议的实现称为提供者(provider)

 

提供者(provider)可以分为两类:STORETRANSPORT。前者实现CamelStore接口,用于邮件的接收,比如POP3IMAP。后者实现CamelTransport接口,用于邮件的发送,比如SMTPSendmail

 

CamelProvider定义了provider的公共数据结构,其中包括像协议、名称、描述、配置和许可证等等信息,其中最重要的是object_types成员,它描述了STORETRANSPORT的类型,用它来创建协议实现的实例。

 

每个provider都以独立的共享库方形提供,并且exportcamel_provider_module_init函数,在该函数内,provider调用camel_provider_register向系统注册自己,只有注册之后才能被使用者使用。而系统在初始化时,调用camel_provider_init去加载所有的provider

 

CamelServiceSTORETRANSPORT共同的基类,它定义了一些两者都要实现的虚函数,比如connect/ disconnect用于建立和断开连接,cancel_connect用于取消连接,query_auth_ types用于查询认证类型。

 

CamelTransport是发送协议必须实现的接口,它只有一个函数send_to,它的参数包括邮件、发件人和收件人等信息。

 

CamelStore是接收协议必须实现的接口,它和IMAP能很好的对应起来。它的要求看起来非常复杂,它并没有提供接收邮件的函数,相反它提供了一些管理folder的函数。要接收邮件,先用get_folder得到CamelFolder,然后调用CamelFolder的函数get_message才行。

 

下面的例子展示了发送邮件的方法:

static char *types[] = { "to", "cc", "bcc" };

 

void sendMail(CamelMimeMessage *msg, CamelException *ex)

{

         CamelInternetAddress *from, *addr, *to;

         CamelTransport *trans;

 

         if (camel_mime_message_get_from(msg) == NULL) {

                   camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot send message: No from address set");

                   return;

         }

 

         trans = (CamelTransport *)camel_session_get_service(session, "smtp://localhost/", ex);

         if (camel_exception_is_set(ex))

                   return;

         camel_service_connect(trans, ex);

         if (camel_exception_is_set(ex))

                   goto noconnect;

 

         to = camel_internet_address_new();

         for (i=0;i<sizeof(types)/sizeof(types[0]);i++) {

                   CamelInternetAddress *addr = camel_mime_message_get_recipients(msg, types[i]);

 

                   if (addr)

                            camel_address_cat(to, addr);

         }

 

         camel_transport_send_to(trans, msg, camel_mime_message_get_from(msg), to, ex);

         camel_object_unref(to);

         camel_transport_disconnect(trans, FALSE, NULL);

noconnect:

         camel_object_unref(trans);

}

 

下面的例子展示了接收邮件的方法:

#include <camel/camel.h>

#include <camel/camel-store.h>

#include <camel/camel-session.h>

#include <camel/camel-folder.h>

 

int main(int argc, char* argv[])

{

    g_type_init();

    g_thread_init(NULL);

    camel_init(NULL, 0);

 

    camel_provider_init();

 

    CamelException* ex = camel_exception_new();

 

    CamelSession* session = CAMEL_SESSION(camel_object_new(CAMEL_SESSION_TYPE));

    camel_session_construct(session, "/tmp");

 

    CamelStore* store = CAMEL_STORE(camel_session_get_service_connected(session,

        "pop://topmailtester:top321@pop.sohu.com",

        CAMEL_PROVIDER_STORE, ex));

 

    CamelFolder* inbox = camel_store_get_inbox(store, ex);

    GPtrArray* uids = camel_folder_get_uids(inbox);

 

    int i = 0;

    for(i = 0; i < uids->len; i++)

    {

        CamelMimeMessage* message = camel_folder_get_message(inbox, uids->pdata[i], CAMEL_FOLDER_RECEIVE_FULL, 0, ex);

        camel_mime_message_dump(message, 1);

        CamelStream* fs = camel_stream_fs_new_with_name(uids->pdata[i], O_CREAT|O_RDWR, 0664);

        camel_data_wrapper_write_to_stream(CAMEL_DATA_WRAPPER(message), fs);

 

        camel_object_unref(CAMEL_OBJECT(fs));

        camel_object_unref(CAMEL_OBJECT(message));

        printf("%p/n", uids->pdata[i]);

    }

   

    camel_folder_free_uids(inbox, uids);

   

    camel_object_unref(CAMEL_OBJECT(store));

    camel_object_unref(CAMEL_OBJECT(session));

    camel_exception_free(ex);

   

    return 0;

}

 

参考资料:

http://www.go-evolution.org

 

~~end~~

 
原文地址:https://www.cnblogs.com/zhangyunlin/p/6167733.html