Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

generatemail.cpp

Go to the documentation of this file.
00001 #include "generatemail.h"
00002 #include "mailwrapper.h"
00003 
00004 #include <libetpan/libetpan.h>
00005 
00006 #include <opie2/odebug.h>
00007 
00008 #include <qt.h>
00009 
00010 using namespace Opie::Core;
00011 const char* Generatemail::USER_AGENT="OpieMail v0.6";
00012 
00013 Generatemail::Generatemail()
00014 {
00015 }
00016 
00017 Generatemail::~Generatemail()
00018 {
00019 }
00020 
00021 void Generatemail::addRcpts( clist *list, mailimf_address_list *addr_list ) {
00022     clistiter *it, *it2;
00023 
00024     for ( it = clist_begin( addr_list->ad_list ); it; it = it->next ) {
00025         mailimf_address *addr;
00026         addr = (mailimf_address *) it->data;
00027 
00028         if ( addr->ad_type == MAILIMF_ADDRESS_MAILBOX ) {
00029             esmtp_address_list_add( list, addr->ad_data.ad_mailbox->mb_addr_spec, 0, NULL );
00030         } else if ( addr->ad_type == MAILIMF_ADDRESS_GROUP ) {
00031             clist *l = addr->ad_data.ad_group->grp_mb_list->mb_list;
00032             for ( it2 = clist_begin( l ); it2; it2 = it2->next ) {
00033                 mailimf_mailbox *mbox;
00034                 mbox = (mailimf_mailbox *) it2->data;
00035                 esmtp_address_list_add( list, mbox->mb_addr_spec, 0, NULL );
00036             }
00037         }
00038     }
00039 }
00040 
00041 char *Generatemail::getFrom( mailimf_field *ffrom) {
00042     char *from = NULL;
00043     if ( ffrom && (ffrom->fld_type == MAILIMF_FIELD_FROM)
00044             && ffrom->fld_data.fld_from->frm_mb_list && ffrom->fld_data.fld_from->frm_mb_list->mb_list ) {
00045         clist *cl = ffrom->fld_data.fld_from->frm_mb_list->mb_list;
00046         clistiter *it;
00047         for ( it = clist_begin( cl ); it; it = it->next ) {
00048             mailimf_mailbox *mb = (mailimf_mailbox *) it->data;
00049             from = strdup( mb->mb_addr_spec );
00050         }
00051     }
00052 
00053     return from;
00054 }
00055 
00056 char *Generatemail::getFrom( mailmime *mail ) {
00057     /* no need to delete - its just a pointer to structure content */
00058     mailimf_field *ffrom = 0;
00059     ffrom = getField( mail->mm_data.mm_message.mm_fields, MAILIMF_FIELD_FROM );
00060     return getFrom(ffrom);
00061 }
00062 
00063 mailimf_field *Generatemail::getField( mailimf_fields *fields, int type ) {
00064     mailimf_field *field;
00065     clistiter *it;
00066 
00067     it = clist_begin( fields->fld_list );
00068     while ( it ) {
00069         field = (mailimf_field *) it->data;
00070         if ( field->fld_type == type ) {
00071             return field;
00072         }
00073         it = it->next;
00074     }
00075 
00076     return NULL;
00077 }
00078 
00079 mailimf_address_list *Generatemail::parseAddresses(const QString&addr ) {
00080     mailimf_address_list *addresses;
00081 
00082     if ( addr.isEmpty() )
00083         return NULL;
00084 
00085     addresses = mailimf_address_list_new_empty();
00086 
00087     bool literal_open = false;
00088     unsigned int startpos = 0;
00089     QStringList list;
00090     QString s;
00091     unsigned int i = 0;
00092     for (; i < addr.length();++i) {
00093         switch (addr[i]) {
00094         case '\"':
00095             literal_open = !literal_open;
00096             break;
00097         case ',':
00098             if (!literal_open) {
00099                 s = addr.mid(startpos,i-startpos);
00100                 if (!s.isEmpty()) {
00101                     list.append(s);
00102                     odebug << "Appended " << s.latin1() << "" << oendl; 
00103                 }
00104                 // !!!! this is a MUST BE!
00105                 startpos = ++i;
00106             }
00107             break;
00108         default:
00109             break;
00110         }
00111     }
00112     s = addr.mid(startpos,i-startpos);
00113     if (!s.isEmpty()) {
00114         list.append(s);
00115         odebug << "Appended " << s.latin1() << "" << oendl; 
00116     }
00117     QStringList::Iterator it;
00118     for ( it = list.begin(); it != list.end(); it++ ) {
00119         int err = mailimf_address_list_add_parse( addresses, (char*)(*it).latin1() );
00120         if ( err != MAILIMF_NO_ERROR ) {
00121             odebug << "Error parsing" << oendl; 
00122             odebug << *it << oendl; 
00123         } else {
00124             odebug << "Parse success! " << (*it).latin1() << "" << oendl; 
00125         }
00126     }
00127     return addresses;
00128 }
00129 
00130 mailmime *Generatemail::buildFilePart(const QString&filename,const QString&mimetype,const QString&TextContent ) {
00131     mailmime * filePart = 0;
00132     mailmime_fields * fields = 0;
00133     mailmime_content * content = 0;
00134     mailmime_parameter * param = 0;
00135     char*name = 0;
00136     char*file = 0;
00137     int err;
00138 
00139     int pos = filename.findRev( '/' );
00140 
00141     if (filename.length()>0) {
00142         QString tmp = filename.right( filename.length() - ( pos + 1 ) );
00143         name = strdup( tmp.latin1() );        // just filename
00144         file = strdup( filename.latin1() );   // full name with path
00145     }
00146 
00147     int disptype = MAILMIME_DISPOSITION_TYPE_ATTACHMENT;
00148     int mechanism = MAILMIME_MECHANISM_BASE64;
00149 
00150     if ( mimetype.startsWith( "text/" ) ) {
00151         param = mailmime_parameter_new( strdup( "charset" ),
00152                                         strdup( "iso-8859-1" ) );
00153         mechanism = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
00154     }
00155 
00156     fields = mailmime_fields_new_filename(
00157                  disptype, name,
00158                  mechanism );
00159     content = mailmime_content_new_with_str( (char*)mimetype.latin1() );
00160     if (content!=0 && fields != 0) {
00161         if (param) {
00162             clist_append(content->ct_parameters,param);
00163             param = 0;
00164         }
00165         if (filename.length()>0) {
00166             QFileInfo f(filename);
00167             param = mailmime_parameter_new(strdup("name"),strdup(f.fileName().latin1()));
00168             clist_append(content->ct_parameters,param);
00169             param = 0;
00170         }
00171         filePart = mailmime_new_empty( content, fields );
00172     }
00173     if (filePart) {
00174         if (filename.length()>0) {
00175             err = mailmime_set_body_file( filePart, file );
00176         } else {
00177             err = mailmime_set_body_text(filePart,strdup(TextContent.data()),TextContent.length());
00178         }
00179         if (err != MAILIMF_NO_ERROR) {
00180             odebug << "Error setting body with file " << file << "" << oendl; 
00181             mailmime_free( filePart );
00182             filePart = 0;
00183         }
00184     }
00185 
00186     if (!filePart) {
00187         if ( param != NULL ) {
00188             mailmime_parameter_free( param );
00189         }
00190         if (content) {
00191             mailmime_content_free( content );
00192         }
00193         if (fields) {
00194             mailmime_fields_free( fields );
00195         } else {
00196             if (name) {
00197                 free( name );
00198             }
00199             if (file) {
00200                 free( file );
00201             }
00202         }
00203     }
00204     return filePart;        // Success :)
00205 
00206 }
00207 
00208 void Generatemail::addFileParts( mailmime *message,const QList<Attachment>&files ) {
00209     const Attachment *it;
00210     unsigned int count = files.count();
00211     odebug << "List contains " << count << " values" << oendl; 
00212     for ( unsigned int i = 0; i < count; ++i ) {
00213         odebug << "Adding file" << oendl; 
00214         mailmime *filePart;
00215         int err;
00216         it = ((QList<Attachment>)files).at(i);
00217 
00218         filePart = buildFilePart( it->getFileName(), it->getMimeType(),"" );
00219         if ( filePart == NULL ) {
00220             odebug << "addFileParts: error adding file:" << oendl; 
00221             odebug << it->getFileName() << oendl; 
00222             continue;
00223         }
00224         err = mailmime_smart_add_part( message, filePart );
00225         if ( err != MAILIMF_NO_ERROR ) {
00226             mailmime_free( filePart );
00227             odebug << "error smart add" << oendl; 
00228         }
00229     }
00230 }
00231 
00232 mailmime *Generatemail::buildTxtPart(const QString&str ) {
00233     mailmime *txtPart;
00234     mailmime_fields *fields;
00235     mailmime_content *content;
00236     mailmime_parameter *param;
00237     int err;
00238 
00239     param = mailmime_parameter_new( strdup( "charset" ),
00240                                     strdup( "iso-8859-1" ) );
00241     if ( param == NULL )
00242         goto err_free;
00243 
00244     content = mailmime_content_new_with_str( "text/plain" );
00245     if ( content == NULL )
00246         goto err_free_param;
00247 
00248     err = clist_append( content->ct_parameters, param );
00249     if ( err != MAILIMF_NO_ERROR )
00250         goto err_free_content;
00251 
00252     fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT);
00253     if ( fields == NULL )
00254         goto err_free_content;
00255 
00256     txtPart = mailmime_new_empty( content, fields );
00257     if ( txtPart == NULL )
00258         goto err_free_fields;
00259 
00260     err = mailmime_set_body_text( txtPart, (char*)str.data(), str.length() );
00261     if ( err != MAILIMF_NO_ERROR )
00262         goto err_free_txtPart;
00263 
00264     return txtPart;     // Success :)
00265 
00266 err_free_txtPart:
00267     mailmime_free( txtPart );
00268 err_free_fields:
00269     mailmime_fields_free( fields );
00270 err_free_content:
00271     mailmime_content_free( content );
00272 err_free_param:
00273     mailmime_parameter_free( param );
00274 err_free:
00275     odebug << "buildTxtPart - error" << oendl; 
00276 
00277     return NULL;        // Error :(
00278 }
00279 
00280 mailimf_mailbox *Generatemail::newMailbox(const QString&name, const QString&mail ) {
00281     return mailimf_mailbox_new( strdup( name.latin1() ),
00282                                 strdup( mail.latin1() ) );
00283 }
00284 
00285 mailimf_fields *Generatemail::createImfFields(const Opie::Core::OSmartPointer<Mail>&mail )
00286 {
00287     mailimf_fields *fields = NULL;
00288     mailimf_field *xmailer = NULL;
00289     mailimf_mailbox *sender=0,*fromBox=0;
00290     mailimf_mailbox_list *from=0;
00291     mailimf_address_list *to=0, *cc=0, *bcc=0, *reply=0;
00292     clist*in_reply_to = 0;
00293     char *subject = strdup( mail->getSubject().latin1() );
00294     int err;
00295     int res = 1;
00296 
00297     sender = newMailbox( mail->getName(), mail->getMail() );
00298     if ( sender == NULL ) {
00299         res = 0;
00300     }
00301 
00302     if (res) {
00303         fromBox = newMailbox( mail->getName(), mail->getMail() );
00304     }
00305     if ( fromBox == NULL ) {
00306         res = 0;
00307     }
00308 
00309     if (res) {
00310         from = mailimf_mailbox_list_new_empty();
00311     }
00312     if ( from == NULL ) {
00313         res = 0;
00314     }
00315 
00316     if (res && from) {
00317         err = mailimf_mailbox_list_add( from, fromBox );
00318         if ( err != MAILIMF_NO_ERROR ) {
00319             res = 0;
00320         }
00321     }
00322 
00323     if (res) to = parseAddresses( mail->getTo() );
00324     if (res) cc = parseAddresses( mail->getCC() );
00325     if (res) bcc = parseAddresses( mail->getBCC() );
00326     if (res) reply = parseAddresses( mail->getReply() );
00327 
00328     if (res && mail->Inreply().count()>0) {
00329         in_reply_to = clist_new();
00330         char*c_reply;
00331         unsigned int nsize = 0;
00332         for (QStringList::ConstIterator it=mail->Inreply().begin();
00333              it != mail->Inreply().end();++it) {
00334             if ((*it).isEmpty())
00335                 continue;
00336             QString h((*it));
00337             while (h.length()>0 && h[0]=='<') {
00338                 h.remove(0,1);
00339             }
00340             while (h.length()>0 && h[h.length()-1]=='>') {
00341                 h.remove(h.length()-1,1);
00342             }
00343             if (h.isEmpty()) continue;
00344             nsize = strlen(h.latin1());
00345             /* yes! must be malloc! */
00346             c_reply = (char*)malloc( (nsize+1)*sizeof(char));
00347             memset(c_reply,0,nsize+1);
00348             memcpy(c_reply,h.latin1(),nsize);
00349             clist_append(in_reply_to,c_reply);
00350             odebug << "In reply to: " << c_reply << "" << oendl; 
00351         }
00352     }
00353 
00354     if (res) {
00355         fields = mailimf_fields_new_with_data( from, sender, reply, to, cc, bcc,
00356                                            in_reply_to, NULL, subject );
00357         if ( fields == NULL ) {
00358             odebug << "Error creating mailimf fields" << oendl; 
00359             res = 0;
00360         }
00361     }
00362     if (res) xmailer = mailimf_field_new_custom( strdup( "User-Agent" ),
00363                                         strdup( USER_AGENT ) );
00364     if ( xmailer == NULL ) {
00365         res = 0;
00366     } else {
00367         err = mailimf_fields_add( fields, xmailer );
00368         if ( err != MAILIMF_NO_ERROR ) {
00369             res = 0;
00370         }
00371     }
00372     if (!res ) {
00373         if (xmailer) {
00374             mailimf_field_free( xmailer );
00375             xmailer = NULL;
00376         }
00377         if (fields) {
00378             mailimf_fields_free( fields );
00379             fields = NULL;
00380         } else {
00381             if (reply)
00382                 mailimf_address_list_free( reply );
00383             if (bcc)
00384                 mailimf_address_list_free( bcc );
00385             if (cc)
00386                 mailimf_address_list_free( cc );
00387             if (to)
00388                 mailimf_address_list_free( to );
00389             if (fromBox) {
00390                 mailimf_mailbox_free( fromBox );
00391             } else if (from) {
00392                 mailimf_mailbox_list_free( from );
00393             }
00394             if (sender) {
00395                 mailimf_mailbox_free( sender );
00396             }
00397             if (subject) {
00398                 free( subject );
00399             }
00400         }
00401     }
00402     return fields;
00403 }
00404 
00405 mailmime *Generatemail::createMimeMail(const Opie::Core::OSmartPointer<Mail> &mail ) {
00406     mailmime *message, *txtPart;
00407     mailimf_fields *fields;
00408     int err;
00409 
00410     fields = createImfFields( mail );
00411     if ( fields == NULL )
00412         goto err_free;
00413 
00414     message = mailmime_new_message_data( NULL );
00415     if ( message == NULL )
00416         goto err_free_fields;
00417 
00418     mailmime_set_imf_fields( message, fields );
00419 
00420     txtPart = buildTxtPart( mail->getMessage() );
00421 
00422     if ( txtPart == NULL )
00423         goto err_free_message;
00424 
00425     err = mailmime_smart_add_part( message, txtPart );
00426     if ( err != MAILIMF_NO_ERROR )
00427         goto err_free_txtPart;
00428 
00429     addFileParts( message, mail->getAttachments() );
00430 
00431     return message;         // Success :)
00432 
00433 err_free_txtPart:
00434     mailmime_free( txtPart );
00435 err_free_message:
00436     mailmime_free( message );
00437 err_free_fields:
00438     mailimf_fields_free( fields );
00439 err_free:
00440     odebug << "createMimeMail: error" << oendl; 
00441 
00442     return NULL;            // Error :(
00443 }
00444 
00445 clist *Generatemail::createRcptList( mailimf_fields *fields ) {
00446     clist *rcptList;
00447     mailimf_field *field;
00448 
00449     rcptList = esmtp_address_list_new();
00450 
00451     field = getField( fields, MAILIMF_FIELD_TO );
00452     if ( field && (field->fld_type == MAILIMF_FIELD_TO)
00453             && field->fld_data.fld_to->to_addr_list ) {
00454         addRcpts( rcptList, field->fld_data.fld_to->to_addr_list );
00455     }
00456 
00457     field = getField( fields, MAILIMF_FIELD_CC );
00458     if ( field && (field->fld_type == MAILIMF_FIELD_CC)
00459             && field->fld_data.fld_cc->cc_addr_list ) {
00460         addRcpts( rcptList, field->fld_data.fld_cc->cc_addr_list );
00461     }
00462 
00463     field = getField( fields, MAILIMF_FIELD_BCC );
00464     if ( field && (field->fld_type == MAILIMF_FIELD_BCC)
00465             && field->fld_data.fld_bcc->bcc_addr_list ) {
00466         addRcpts( rcptList, field->fld_data.fld_bcc->bcc_addr_list );
00467     }
00468 
00469     return rcptList;
00470 }

Generated on Sat Nov 5 16:17:37 2005 for OPIE by  doxygen 1.4.2