kisli / vmime Goto Github PK
View Code? Open in Web Editor NEWVMime Mail Library
Home Page: http://www.vmime.org
License: GNU General Public License v3.0
VMime Mail Library
Home Page: http://www.vmime.org
License: GNU General Public License v3.0
VMime is a powerful C++ class library for working with RFC-822 and MIME messages and Internet messaging services like IMAP, POP or SMTP. With VMime you can parse, generate and modify messages, and also connect to store and transport services to receive or send messages over the Internet. The library offers all the features to build a complete mail client. Key Features ------------ * it is free software! GNU GPL license (Commercial licenses available!) * fully RFC-compliant implementation * object-oriented and modular design * very easy-to-use (intuitive design) * well documented code * very high reliability * maximum portability Features Overview ----------------- * RFC-2822 and multipart messages * aggregate documents and embedded objects * 8-bit MIME and encoded word extensions * full support for attachments * POP3, IMAP, SMTP, maildir and sendmail * SSL/TLS security layer and X.509 certificates (using GNU TLS) * SASL authentication (using GNU SASL)
The example7.cpp source would not compile initially with these errors in v0.9.1 using the following command line:
$ g++ -O2 -I$INSTALLDIR/website/include example7.cpp -o example7 -L$INSTALLDIR/website/lib -lvmime
example7.cpp: In function 'int main()':
example7.cpp:46:2: error: 'encoderFactory' is not a member of 'vmime'
example7.cpp:46:25: error: 'ef' was not declared in this scope
example7.cpp:46:37: error: 'vmime::encoderFactory' has not been declared
example7.cpp:52:42: error: ISO C++ forbids declaration of 'type name' with no type
example7.cpp:52:61: error: template argument 1 is invalid
example7.cpp:53:8: error: invalid type in declaration before '=' token
example7.cpp:55:29: error: base operand of '->' is not a pointer
example7.cpp:57:15: error: 'encoder' is not a member of 'vmime'
example7.cpp:57:15: error: 'encoder' is not a member of 'vmime'
example7.cpp:57:29: error: template argument 1 is invalid
example7.cpp:57:33: error: invalid type in declaration before '=' token
example7.cpp:57:38: error: base operand of '->' is not a pointer
example7.cpp:59:40: error: base operand of '->' is not a pointer
But after analyzing the compiler error messages, and using the mime-book.pdf as a guide, finally fixed the source code (see below) which now compiles and runs just fine:
Best regards,
Tom Straub
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2009 Vincent Richard <[email protected]>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
//
// EXAMPLE DESCRIPTION:
// ====================
// This sample program demonstrates how to enumerate encoders and
// messaging services in VMime.
//
// For more information, please visit:
// http://www.vmime.org/
//
#include <iostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
int main()
{
// VMime initialization
vmime::platform::setHandler<vmime::platforms::posix::posixHandler>();
// Enumerate encoders
vmime::utility::encoder::encoderFactory* ef = vmime::utility::encoder::encoderFactory::getInstance();
std::cout << "Available encoders:" << std::endl;
for (int i = 0 ; i < ef->getEncoderCount() ; ++i)
{
vmime::ref <const vmime::utility::encoder::encoderFactory::registeredEncoder>
enc = ef->getEncoderAt(i);
std::cout << " * " << enc->getName() << std::endl;
vmime::ref <vmime::utility::encoder::encoder> e = vmime::utility::encoder::encoderFactory::getInstance()->create("base64");
std::vector <vmime::string> props = e->getAvailableProperties();
for (std::vector <vmime::string>::const_iterator it = props.begin() ; it != props.end() ; ++it)
std::cout << " - " << *it << std::endl;
}
std::cout << std::endl;
// Enumerate messaging services and their properties
vmime::net::serviceFactory* sf = vmime::net::serviceFactory::getInstance();
std::cout << "Available messaging services:" << std::endl;
for (int i = 0 ; i < sf->getServiceCount() ; ++i)
{
const vmime::net::serviceFactory::registeredService& serv = *sf->getServiceAt(i);
std::cout << " * " << serv.getName() << std::endl;
std::vector <vmime::net::serviceInfos::property> props =
serv.getInfos().getAvailableProperties();
for (std::vector <vmime::net::serviceInfos::property>::const_iterator it = props.begin() ;
it != props.end() ; ++it)
{
const vmime::net::serviceInfos::property& p = *it;
const vmime::string name = serv.getInfos().getPropertyPrefix() + p.getName();
vmime::string type;
switch (p.getType())
{
case vmime::net::serviceInfos::property::TYPE_INTEGER: type = "TYPE_INTEGER"; break;
case vmime::net::serviceInfos::property::TYPE_STRING: type = "TYPE_STRING"; break;
case vmime::net::serviceInfos::property::TYPE_BOOL: type = "TYPE_BOOL"; break;
default: type = "(unknown)"; break;
}
vmime::string flags;
if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_REQUIRED)
flags += " FLAG_REQUIRED";
if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_HIDDEN)
flags += " FLAG_HIDDEN";
std::cout << " - " << serv.getInfos().getPropertyPrefix() + p.getName();
std::cout << " (type=" << type << ", flags=" << flags;
std::cout << ", defaultValue=" << p.getDefaultValue() << ")" << std::endl;
}
}
std::cout << std::endl;
}
headerField parser in case of folded line removes only one CRLF followed by SPACE whereas rfc2822 says: Unfolding is accomplished by simply removing any CRLF that is immediately followed by WSP
Hey,
I currently install vmime in my mac. However, I compile example1 with:
g++ exampl1.cpp -lvmime -o example
It get compiled. However, it gives out errorss when I execute the executable:
dyld: lazy symbol binding failed: Symbol not found: _gcry_control
Referenced from: /usr/local/lib/libvmime.0.dylib
Expected in: flat namespace
dyld: Symbol not found: _gcry_control
Referenced from: /usr/local/lib/libvmime.0.dylib
Expected in: flat namespace
Could you give me a help???
posixHandler's getHostName does:
std::vector <vmime::string> hostnames;
char buffer[256];
// Try with 'gethostname'
::gethostname(buffer, sizeof(buffer));
[...]
hostnames.push_back(buffer);
// And with 'gethostbyname'
struct hostent* he = ::gethostbyname(buffer);
[...]
// Find a Fully-Qualified Domain Name (FQDN)
for (unsigned int i = 0 ; i < hostnames.size() ; ++i)
{
if (hostnames[i].find_first_of(".") != vmime::string::npos)
return (hostnames[i]);
}
If hostnames[0] (i.e. the result of gethostname) contains a '.', then the result of gethostbyname is ignored. So please don't call it. (This breaks machines that have a fully-qualified hostname and are having DNS issues.)
hdr->Subject()->getValue().dynamicCast <vmime::text>()->getConvertedText(ch)
and
hdr->From()->getValue().dynamicCast <vmime::mailbox>()->getName().getConvertedText(ch)
in msg.tex.
I have to add a 'const':
hdr->From()->getValue().dynamicCast <const vmime::mailbox>()->getName().getConvertedText(ch)
And,
vmime::text subject = msg->getHeader()->Subject()->getValue();
in basics.tex
throws:
error: conversion from ‘vmime::utility::ref<const vmime::headerFieldValue>’ to non-scalar type ‘const vmime::text’ requested
I see that IDLE support is on the development roadmap (http://www.vmime.org/development.html) but it appears to have been rotting there since Sept 2010. Is there a hidden complexity in integrating this with the VMime codebase that I am missing?
If I was going to attempt to do the integration, is there anything I need to look out for to get my changes accepted?
Was the name change for the pkg-config file intentional? Not sure if the repo packagers will be happy about this.
FindIconv provides a full path to the iconv library file, such as "/libiconv.a". This ends up in VMIME_PKGCONFIG_LIBS and then libvime.pc Libs.private.
The problem is that this leads to the wrong order when linking to static libvmime when using "pkg-config --static --libs libvmime, i.e.:
/usr/lib/libiconv.a -L/usr/lib -lvmime
The result is unsatisfied iconv symbols in libvmime.
Building libvmime 0.9.1 fails on OS X 10.9 Mavericks:
/bin/sh ../libtool --tag=CXX --mode=compile /usr/bin/clang++ -DHAVE_CONFIG_H -I. -I.. -I/opt/local/include -I.. -D_REENTRANT=1 -D_THREAD_SAFE=1 -I/opt/local/include -I/opt/local/include/p11-kit-1 -I/opt/local/include -fno-common -DPIC -ansi -pedantic -W -Wall -Wpointer-arith -Wold-style-cast -Wconversion -isystem/opt/local/include -O2 -c -o utility_smartPtrInt.lo utility_smartPtrInt.cpp
libtool: compile: /usr/bin/clang++ -DHAVE_CONFIG_H -I. -I.. -I/opt/local/include -I.. -D_REENTRANT=1 -D_THREAD_SAFE=1 -I/opt/local/include -I/opt/local/include/p11-kit-1 -I/opt/local/include -fno-common -DPIC -ansi -pedantic -W -Wall -Wpointer-arith -Wold-style-cast -Wconversion -isystem/opt/local/include -O2 -c utility_smartPtrInt.cpp -fno-common -DPIC -o .libs/utility_smartPtrInt.o
In file included from utility_smartPtrInt.cpp:24:
../vmime/utility/smartPtrInt.hpp:59:2: error: unknown type name 'pthread_mutex_t'
pthread_mutex_t m_mutex;
^
utility_smartPtrInt.cpp:41:9: error: cannot initialize return object of type 'vmime::utility::refManager *' with an rvalue of type 'vmime::utility::refManagerImpl *'
return new refManagerImpl(obj);
^~~~~~~~~~~~~~~~~~~~~~~
utility_smartPtrInt.cpp:110:3: error: cannot initialize object parameter of type 'vmime::utility::refManager' with an expression of type 'vmime::utility::refManagerImpl'
deleteObjectImpl(m_object);
^~~~~~~~~~~~~~~~
In file included from utility_smartPtrInt.cpp:24:
In file included from ../vmime/utility/smartPtrInt.hpp:29:
../vmime/utility/smartPtr.hpp:131:6: warning: private field 'foo' is not used [-Wunused-private-field]
int foo;
^
In file included from utility_smartPtrInt.cpp:24:
../vmime/utility/smartPtrInt.hpp:59:18: warning: private field 'm_mutex' is not used [-Wunused-private-field]
pthread_mutex_t m_mutex;
^
2 warnings and 3 errors generated.
This was also reported to the MacPorts project; you can find the full log attached to that ticket.
Configuring libvmime 0.9.1 fails if any broken pkg-config file exists in the pkg-config directory, as is currently the case in MacPorts when cyrus-sasl2 is installed. libvmime does not use cyrus-sasl2, but having cyrus-sasl2 installed causes libvmime to fail its configuration phase.
This appears to be because libvmime's SConstruct is running pkg-config --list-all
, followed by grep
and cut
, to find out if a package is installed. Surely there's a more straightforward way to ask pkg-config if a package is installed or not, that doesn't involve a full scan of all installed packages.
Hallo,
can anyone give me an example of how to extract the modification date of a file attachment while parsing a message.
With the following code I get a Segmentation Fault while executing:
...
vmime::messageParser mp(msg);
int attz=0;
int ahz = mp.getAttachmentCount();
for (int i = 0 ; i < ahz ; ++i) {
vmime::ref att = mp.getAttachmentAt(i);
vmime::string attData;
vmime::utility::outputStreamStringAdapter out(attData);
att->getData()->extract(out);
const vmime::ref fatt = att.staticCast ();
const vmime::fileAttachment::fileInfo &gFI = fatt->getFileInfo();
if ((&gFI)->hasReadDate()) {
const vmime::datetime *dt = &(gFI.getReadDate());
int jahr,mon,tag,std,min,sek,zone;
dt->getTime(std,min,sek,zone);
dt->getDate(jahr,mon,tag);
}
}
Thany You in advance
Greetings,
when compiling libvmime I get this error "gnutls/extra.h: No such file or directory"
Is there a way to disable a feature or something, so that the gnutls/extra.h is not needed?
I compiled gnutls-3.1.7 and got theseheaders.
ls /usr/include/gnu
abstract.h compat.h crypto.h dtls.h gnutls.h gnutlsxx.h ocsp.h openpgp.h openssl.h pkcs11.h pkcs12.h tpm.h x509.h xssl.h
I'll be glad about any advice.
greetings
So, it's been a while since I've installed something from source, but according to the manual it looks like vmime is a traditional ./configure, make, make install. I just cloned the git repository but I don't see the configure script. Am I missing something here? Has the build process changed?
It seems that all mails are send as quoted-printable, but all line breaks are send as "=0D=0A" instead of just "\r\n", and that is just wrong for text. It does make sense for non-text parts, but you have "Content-Type: text/plain". You should just send it as \r\n
Please see RFC2045 section 6.7 (4).
Develop a new store implementation for managing 'mbox' mail stores.
I'm following the instruction from the documentation and trying to extract text part from a message that consists of text body and 4 img/jpeg attachments.
When I do
message = folder->getMessage(x);
folder->fetchMessage(message, vmime::net::folder::FETCH_STRUCTURE);
vmime::utility::outputStreamAdapter out(std::cout);
message->extractPart(messages[i]->getStructure()->getPartAt(0),out);
this will printout all 5 extracted parts.
But when I do
message->extractPart(messages[i]->getStructure()->getPartAt(0)->getPartAt(0),out);
this results in a segfault. Is the syntax wrong?
And if I do
message->getParsedMessage()->getBody()->getPartAt(0)->getBody()->getContents()->extract(out);
this doesn't segfault but prints out nothing. I've read that getParsedMessage() only fetches the structure and extract() fetches the actual data. Shouldn't the above code print out the text body of the message?
I try to extract message with attachment which weighs more than 200MB using vmime (libvmime-0.9.1)
vmime::ref < vmime::net::message> msg;
............
vmime::string buffer;
vmime::utility::outputStreamStringAdapter bufferStream(buffer);
msg->extract(bufferStream);
vmime::messageParser mp(buffer);
When I do extracting I have a Runtime Error - std::bad_alloc though I've got enough memory.
The same problem I've got when I try to extract an attachment from a message.
I've found in the vmime's libraries a function "extractPart". But there is no documentation or examples how this function works.
Or, maybe is there any way to avoid using the "extract" function?
vmime::messageParser mp(bufferStream)?
vmime/examples$ g++ -o example6 example6.cpp -I/usr/local/include/vmime
example6.cpp:295: error: ISO C++ forbids declaration of ‘type name’ with no type
example6.cpp:295: error: template argument 1 is invalid
example6.cpp: In function ‘void printStructure(int, int)’:
example6.cpp:297: error: base operand of ‘->’ is not a pointer
example6.cpp:299: error: ISO C++ forbids declaration of ‘type name’ with no type
example6.cpp:299: error: template argument 1 is invalid
example6.cpp:299: error: invalid type in declaration before ‘=’ token
example6.cpp:299: error: base operand of ‘->’ is not a pointer
example6.cpp:304: error: base operand of ‘->’ is not a pointer
example6.cpp:305: error: base operand of ‘->’ is not a pointer
example6.cpp:306: error: base operand of ‘->’ is not a pointer
example6.cpp:309: error: base operand of ‘->’ is not a pointer
example6.cpp: In function ‘void connectStore()’:
example6.cpp:632: error: invalid conversion from ‘const void*’ to ‘int’
example6.cpp:632: error: initializing argument 1 of ‘void printStructure(int, int)’
Here is a source you can use for an example of sending SMTP messages using the VMIME library using parameters from the command line. Feel free to alter it in any way you see fit... Tom
// $Id$
/**
* @file testemailsmtp.cpp
* @brief Test VMime email sending (SMTP) of email messages (TLS and SSL not supported)
* @author Thomas Straub
* @version 0.1
* @note Compile and link with: g++ -O2 testemailsmtp.cpp -o testemailsmtp -lvmime
*/
// $Log$
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vmime/vmime.hpp>
#include <vmime/platforms/posix/posixHandler.hpp>
using namespace std;
/**
* @fn "void show_usage ()"
* @brief Show commandline usage on standard output
* @details Commandline usage is shown on the standard output along with
* examples of each parameter in the -m option string.
* @return None
*/
void show_usage () {
cout << "\nSends one or more emails by SMTP protocol using VMIME library\n\n"
<< "Commandline Parameters:\n"
<< " -m 'optionstring' [-m 'optionstring']...\n"
<< "Where optionstring contains name/value pairs delimited by colons:\n"
<< " sender=emailaddress (example: \"[email protected]\")\n"
<< " recipient=emailaddress (example: \"[email protected]\")\n"
<< " subject=words (example: \"subject=subject line text\")\n"
<< " message=words (example: \"message=single line of text\")\n"
<< " server=servername (example: \"server=smtp.domain.com\")\n"
<< " port=serverport (example: \"port=25\")\n"
<< " auth=boolean (example: \"auth=true\" {or} \"auth=false\")\n"
<< " username=word (example: \"username=accountname\")\n"
<< " password=word (example: \"password=passwordtext\")\n"
<< "Note that username and password are not required if \"auth=false\"\n"
<< "\n";
}
/**
* @fn "std::ostream & operator << (std::ostream & i_reostOut, const vmime::exception & i_reexcVmime)"
* @brief Add recursive printing of VMIME exception what() strings
* @details Taken from @c example6.cpp supplied in the VMIME v0.9.1 source code,
* this function is called from within a @c catch scope to print what() strings
* generated by a @c vmime::exception that is caught by @c try/catch code.
* @return std::ostream = Reference of output stream with what() text appended to it
*/
std::ostream & operator << (std::ostream & i_reostOut, const vmime::exception & i_reexcVmime)
{
i_reostOut << "∗ vmime::exceptions::" << i_reexcVmime.name() << ": '" << i_reexcVmime.what() << "'\n";
if (i_reexcVmime.other() != NULL) i_reostOut << *i_reexcVmime.other();
return i_reostOut;
}
/**
* @fn "void send_messages (vector< map<string, string> > i_vecmapMessages)"
* @brief Send all messages using SMTP protocol with VMIME library
* @details The input parameter @c i_vecmapMessages contains a list of pairs of
* names and values of parts of a email messages to be sent using the SMTP email
* protocol. Each vector entry is a new message. The following names are supported:
* - sender = sender of message (eg: "[email protected]")
* - recipient = recipient of message (eg: "[email protected]")
* - subject = subject line text of message (eg: "This is a subject line")
* - server = SMTP server name (eg: "smtp.sendingdomain.com")
* - port = SMTP server port (eg: "26") [optional, default is "25"]
* - auth = flag indicating the authorization is allowed (eg: "true" (or) "false")
* - username = authorization email account username of sender (eg: "accountname")
* - password = authorization email account password of sender (eg: "accountpass")
* @return None
*/
void send_messages (vector< map<string, string> > i_vecmapMessages)
{
int l_inMessages = i_vecmapMessages.size();
for (int l_inMessage = 0; l_inMessage < l_inMessages; ++l_inMessage)
{
if (i_vecmapMessages[l_inMessage].find("port") == i_vecmapMessages[l_inMessage].end()) {
i_vecmapMessages[l_inMessage]["port"] = "25";
}
cout << "\nPreparing to send email number " << (l_inMessage + 1) << " using SMTP protocol...\n"
<< " From: '" << i_vecmapMessages[l_inMessage]["sender"] << "'\n"
<< " To: '" << i_vecmapMessages[l_inMessage]["recipient"] << "'\n"
<< " Subject: '" << i_vecmapMessages[l_inMessage]["subject"] << "'\n"
<< " Server: '" << i_vecmapMessages[l_inMessage]["server"] << "'\n"
<< " Port: '" << i_vecmapMessages[l_inMessage]["port"] << "'\n"
<< " Auth: '" << i_vecmapMessages[l_inMessage]["auth"] << "'\n";
if (i_vecmapMessages[l_inMessage]["auth"] == "true") {
cout << " Account: '" << i_vecmapMessages[l_inMessage]["username"] << "'\n"
<< " Password: '" << i_vecmapMessages[l_inMessage]["password"] << "'\n";
}
cout << " Message: '" << i_vecmapMessages[l_inMessage]["message"] << "'\n\n";
vmime::text l_vtxtSubject (i_vecmapMessages[l_inMessage]["subject"]);
vmime::mailbox l_vmbxSender (i_vecmapMessages[l_inMessage]["sender"]);
vmime::ref <vmime::mailbox> l_vrefRecipient = vmime::create<vmime::mailbox>(i_vecmapMessages[l_inMessage]["recipient"]);
vmime::ref <vmime::stringContentHandler> l_vrefMessage = vmime::create<vmime::stringContentHandler>(i_vecmapMessages[l_inMessage]["message"]);
vmime::messageBuilder l_vmbrMessageBuilder;
vmime::ref <vmime::net::session> l_vsesNetSession = vmime::create <vmime::net::session>();
vmime::ref <vmime::net::transport> l_vtraNetTransport = l_vsesNetSession->getTransport("smtp");
l_vmbrMessageBuilder.setSubject(l_vtxtSubject);
l_vmbrMessageBuilder.setExpeditor(l_vmbxSender);
l_vmbrMessageBuilder.getRecipients().appendAddress(l_vrefRecipient);
l_vmbrMessageBuilder.getTextPart()->setCharset(vmime::charsets::UTF_8);
l_vmbrMessageBuilder.getTextPart()->setText(l_vrefMessage);
l_vtraNetTransport->setProperty("server.address", i_vecmapMessages[l_inMessage]["server"]);
l_vtraNetTransport->setProperty("server.port", atoi(i_vecmapMessages[l_inMessage]["port"].c_str()));
l_vtraNetTransport->setProperty("options.need-authentication", (i_vecmapMessages[l_inMessage]["auth"] == "true" ? true : false));
l_vtraNetTransport->setProperty("auth.username", i_vecmapMessages[l_inMessage]["username"]);
l_vtraNetTransport->setProperty("auth.password", i_vecmapMessages[l_inMessage]["password"]);
cout << "Sending...";
vmime::ref <vmime::message> l_vmsgMessage = l_vmbrMessageBuilder.construct();
l_vtraNetTransport->connect();
l_vtraNetTransport->send(l_vmsgMessage);
l_vtraNetTransport->disconnect();
cout << "Done.\n\n";
}
}
/**
* @fn "string get_value(const string & i_strOptions, const string & i_strName)"
* @brief Get value of a colon delimited name/value pair from option string
* @details The commandline parameter @c -m option string contains a list of
* name/value pairs delimited by colons. An example option string is below:
* - "server=smtp.domain.com:port=25:auth=false"
* This function parses the value of the option string pair out of the passed
* input parameter @c i_strOptions using the passed name @c i_strName input
* parameter, and returns the value as a @c std::string object.
* @return std::string = Value of passed name/value pair in passed option string
* or a zero-length string if name does not exist in option string.
*/
string get_value(const string & i_strOptions, const string & i_strName) {
int l_inPos = 0;
int l_inLen = 0;
string l_strValue = "";
if ((l_inPos = i_strOptions.find(i_strName)) != string::npos) {
l_inLen = i_strOptions.find(':', l_inPos);
if (l_inLen != string::npos) l_inLen -= l_inPos;
string l_strPair = i_strOptions.substr(l_inPos, l_inLen);
if ((l_inPos = l_strPair.find('=')) != string::npos) {
++l_inPos;
l_strValue = l_strPair.substr(l_inPos, string::npos);
}
}
return l_strValue;
}
int main(int i_inArgc, char ** i_popochArgv) {
char l_chOption = 0; // character option
if (i_inArgc < 3) {
show_usage();
exit(EXIT_FAILURE);
}
vector< map<string, string> > l_vecmapEmailList;
while ((l_chOption = getopt(i_inArgc, i_popochArgv, "m:")) > 0) {
switch (l_chOption) {
case 'm': {
string l_strOption (optarg);
map<string, string> l_mapEmail;
l_mapEmail["subject"] = get_value(l_strOption, "subject");
l_mapEmail["sender"] = get_value(l_strOption, "sender");
l_mapEmail["recipient"] = get_value(l_strOption, "recipient");
l_mapEmail["message"] = get_value(l_strOption, "message");
l_mapEmail["server"] = get_value(l_strOption, "server");
l_mapEmail["port"] = get_value(l_strOption, "port");
l_mapEmail["auth"] = get_value(l_strOption, "auth");
if (l_mapEmail["auth"] == "true") {
l_mapEmail["username"] = get_value(l_strOption, "username");
l_mapEmail["password"] = get_value(l_strOption, "password");
}
l_vecmapEmailList.push_back(l_mapEmail);
break;
}
default: {
show_usage();
exit(EXIT_FAILURE);
}
}
}
try {
// VMime initialization
vmime::platform::setHandler<vmime::platforms::posix::posixHandler>();
// Send messages via SMTP
send_messages(l_vecmapEmailList);
}
catch (vmime::exception & l_excVmime) // VMime exception
{
std::cout << l_excVmime;
exit(EXIT_FAILURE);
}
catch (std::exception & l_excStd) // Standard exception
{
std::cout << "std::exception: '" << l_excStd.what() << "'\n";
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
I get a SEGFAULT when sending email asynchronously, but only sometimes. This wasn't a problem on a single core CPU, but is on a multi-code CPU.
#0 0x00412996 in vmime::utility::refCounter::operator long at utility_smartPtr.cpp:158
#1 0x004129ca in vmime::utility::refManager::addStrong at utility_smartPtr.cpp:47
#2 0x004404a4 in _ZN5vmime7utility3refINS_8platform7handlerEEcvNS1_IT_EEIKS3_EEv [inlined] at smartPtr.hpp:251
#3 0x004404a4 in vmime::platform::getHandler at platform.hpp:143
#4 0x004404a4 in vmime::net::smtp::SMTPResponse::readResponseLine at smartPtr.hpp:149
#5 0x0044099a in vmime::net::smtp::SMTPResponse::getNextResponse at net_smtp_SMTPResponse.cpp:160
#6 0x00441374 in vmime::net::smtp::SMTPResponse::readResponse at net_smtp_SMTPResponse.cpp:96
#7 0x00441a68 in vmime::net::smtp::SMTPResponse::readResponse at net_smtp_SMTPResponse.cpp:88
#8 0x00443f1d in ~ref [inlined] at net_smtp_SMTPTransport.cpp:622
#9 0x00443f1d in ~ref [inlined] at smartPtr.hpp:175
#10 0x00443f1d in vmime::net::smtp::SMTPTransport::readResponse at net_smtp_SMTPTransport.cpp:622
#11 0x004465cc in attachvmime::net::smtp::SMTPResponse [inlined] at net_smtp_SMTPTransport.cpp:196
#12 0x004465cc in vmime::utility::refvmime::net::smtp::SMTPResponse::operator= at smartPtr.hpp:286
#13 0x004465cc in vmime::net::smtp::SMTPTransport::helo at net_smtp_SMTPTransport.cpp:196
#14 0x004476cb in vmime::net::smtp::SMTPTransport::connect at net_smtp_SMTPTransport.cpp:138
The problem appears to be that the refManager is null:
(gdb) p *platform::sm_handler.m_ptr
$9 = {vmime::object = {_vptr$object = 0x5c0258, m_refMgr = 0x0}, }
I am trying to compile vmime with codeblocks in windows XP changing studio project files to C::B project files.
.\vmime\propertySet.hpp|117|error: explicit specialization in non-namespace scope 'class vmime::propertySet::property'
Looking for answers i found that code must change for default C++.
At link http://stackoverflow.com/questions/3052579/explicit-specialization-in-non-namespace-scope there is a solution in code i thing.
As i see most projects use MS VC++ traditionally, but i thing CodeBlocks is more good and open source, and for all OS, and for start up has many open source type of projects to made with ready for use code. I it has and vmime i will it easy for me to study the use of it. Now? So i write to you for that.
C::B projects at start up page.
ARM Project, AVR Project, Code::Blocks plugin,Console application, D application, Direct/X project, Dynamic Link Empty Library, FLTK project, Fortran DLL, Fortran application, Fortran library, GLKW project, GLUT project, GLUT project, GTK+ project, Irrlicht project, Kernel Mode Driver, Lightfeather project, MCS 51 Project Matlab project, Orge project, OpenGL project, PowerPC Project, SFML project, STL port application, QT4 project, Shared library, SDL project, Win32 GUI project, TriCore Project, Static library, wxWidgets project.
||=== vmime, Debug Win32 ===|
.\vmime\propertySet.hpp|117|error: explicit specialization in non-namespace scope 'class vmime::propertySet::property'|
.\vmime\propertySet.hpp|117|error: extra qualification 'vmime::propertySet::property::' on member 'setValue' [-fpermissive]|
.\vmime\propertySet.hpp|117|error: 'void vmime::propertySet::property::setValue(const string&)' cannot be overloaded|
.\vmime\propertySet.hpp|76|error: with 'void vmime::propertySet::property::setValue(const string&)'|
.\vmime\propertySet.hpp|122|error: explicit specialization in non-namespace scope 'class vmime::propertySet::property'|
.\vmime\propertySet.hpp|123|error: extra qualification 'vmime::propertySet::property::' on member 'setValue' [-fpermissive]|
.\vmime\propertySet.hpp|128|error: explicit specialization in non-namespace scope 'class vmime::propertySet::property'|
.\vmime\propertySet.hpp|129|error: extra qualification 'vmime::propertySet::property::' on member 'getValue' [-fpermissive]|
.\vmime\propertySet.hpp|129|error: 'vmime::string vmime::propertySet::property::getValue() const' cannot be overloaded|
.\vmime\propertySet.hpp|70|error: with 'const string& vmime::propertySet::property::getValue() const'|
.\vmime\propertySet.hpp|134|error: explicit specialization in non-namespace scope 'class vmime::propertySet::property'|
.\vmime\propertySet.hpp|135|error: extra qualification 'vmime::propertySet::property::' on member 'getValue' [-fpermissive]|
.\vmime\propertySet.hpp|135|error: 'bool vmime::propertySet::property::getValue() const' cannot be overloaded|
.\vmime\propertySet.hpp|70|error: with 'const string& vmime::propertySet::property::getValue() const'|
.\vmime\propertySet.hpp|380|error: explicit specialization in non-namespace scope 'class vmime::propertySet'|
.\vmime\propertySet.hpp|386|error: explicit specialization in non-namespace scope 'class vmime::propertySet'|
.\vmime\propertySet.hpp|392|error: explicit specialization in non-namespace scope 'class vmime::propertySet'|
.\vmime\propertySet.hpp|393|error: 'static bool vmime::propertySet::valueFromString(const string&)' cannot be overloaded|
.\vmime\propertySet.hpp|381|error: with 'static vmime::string vmime::propertySet::valueFromString(const string&)'|
.\vmime\propertySet.hpp|410|error: explicit specialization in non-namespace scope 'class vmime::propertySet'|
||=== Build finished: 20 errors, 0 warnings (0 minutes, 5 seconds) ===|
Add a feature to permit downloading messages by their UIDs and fetch some attributes at the same time, to save a roundtrip to the server (getMessagesByUID + fetchMessages).
Add a function to return the permanent flags supported by the server (POP3/IMAP/maildir).
"[Parser] MUST be able to handle padding added by message transports".
See: http://tools.ietf.org/html/rfc2046#appendix-A
Is there a good way to configure a static only build of vmime using cmake? I do this currently by hacking the configuration files. See the first patch in file here:
https://github.com/mxe/mxe/blob/8219b36f3f75b263a051ffb45f086410179640d6/src/vmime-1-fixes.patch
when compiling on Windows with mingw-w64, 64bits :
libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I/opt/win64/deps/include -I.. -D_REENTRANT=1 -D_THREAD_SAFE=1 -DDLL_EXPORT -DPIC -ansi -pedantic -W -Wall -Wpointer-arith -Wold-style-cast -Wconversion -I/opt/win64/deps/include -O2 -c utility_smartPtrInt.cpp -DDLL_EXPORT -DPIC -o .libs/utility_smartPtrInt.o
In file included from c:\mingw\mingw64\bin../lib/gcc/x86_64-w64-mingw32/4.7.2/../../../../x86_64-w64-mingw32/include/objbase.h:153:0,
from c:\mingw\mingw64\bin../lib/gcc/x86_64-w64-mingw32/4.7.2/../../../../x86_64-w64-mingw32/include/ole2.h:16,
from c:\mingw\mingw64\bin../lib/gcc/x86_64-w64-mingw32/4.7.2/../../../../x86_64-w64-mingw32/include/windows.h:94,
from utility_smartPtrInt.cpp:28:
c:\mingw\mingw64\bin../lib/gcc/x86_64-w64-mingw32/4.7.2/../../../../x86_64-w64-mingw32/include/unknwn.h: In member function 'HRESULT IUnknown::QueryInterface(Q*)':
c:\mingw\mingw64\bin../lib/gcc/x86_64-w64-mingw32/4.7.2/../../../../x86_64-w64-mingw32/include/unknwn.h:70:82: error: '' cannot appear in a constant-expression
c:\mingw\mingw64\bin../lib/gcc/x86_64-w64-mingw32/4.7.2/../../../../x86_64-w64-mingw32/include/unknwn.h:70:82: error: a function call cannot appear in a constant-expression
IMAPMessage::extract() should extract the whole message but with libvmime 0.9.2 and current git it does not. It just extracts the body.
The API doc says:
Extract the whole message data (header + contents).
But a call like
vmime::utility::outputStreamByteArrayAdapter out(raw_arr);
msg->extract(out);
yields following IMAP command:
FETCH 1 BODY[TEXT]
And according to RFC 3501:
The TEXT part specifier refers to the text body of the message,
omitting the RFC-2822 header.
The old libvmime 0.8.1 code yields:
FETCH 1 BODY[]
which works as expected because:
An empty section
specification refers to the entire message, including the
header.
(again RFC 3501)
This is a regression. Is used to work with libvmime 0.8.1 and 0.9svn.
For a real example, where the regression introduces a bug see mailcp.
Thanks for your awesome work.
And I found no file named "FindOpenSSL.cmake" in the directory cmake.
Add an option to set the envelope sender with either sendmail or SMTP.
/home/rmak/temp/vmime/vmime/utility/url.hpp:41: error: variable ‘vmime::utility::VMIME_EXPORT vmime::utility::url’ has initializer but incomplete type
/home/rmak/temp/vmime/vmime/utility/url.hpp:43: error: expected primary-expression before ‘public’
/home/rmak/temp/vmime/vmime/utility/url.hpp:43: error: expected ‘}’ before ‘public’
/home/rmak/temp/vmime/vmime/utility/url.hpp:43: error: expected ‘,’ or ‘;’ before ‘public’
Hello,
I downloaded the newest version of vmime and unzipped it. I created a new folder build in it and did: cmake ../
which works fine.
After executing make it breaks
zarafa/vmime-master/build# make
[ 0%] Building CXX object CMakeFiles/vmime.dir/src/address.cpp.o
In file included from /backup/fes-a120d19nas/zarafa/vmime-master/vmime/address.hpp:28:0,
from /backup/fes-a120d19nas/zarafa/vmime-master/src/address.cpp:24:
/backup/fes-a120d19nas/zarafa/vmime-master/vmime/base.hpp:35:28: fatal error: vmime/config.hpp: No such file or directory
compilation terminated.
make[2]: *** [CMakeFiles/vmime.dir/src/address.cpp.o] Error 1
make[1]: *** [CMakeFiles/vmime.dir/all] Error 2
make: *** [all] Error 2
I tried to find the file, but it is really missing when trying to fint it with "ls ../vmime/conf"
Do you need any logs?
greetings
In your CMakeLists.txt at line 20, you have
include(CheckIncludeFileCxx)
This should be
include(CheckIncludeFileCXX)
^^--- Uppercase
Implement a feature into SMTP transport to log in to a POP/IMAP server before connecting to the SMTP server (spam protection).
More information here:
E.g., when logging on to imap.mail.me.com, the CN is *.mail.me.com. X509Certificate_OpenSSL::verifyHostName does not seem to do wildcard matching, so the Certificate cannot be verified against hostname.
I've added a simple wildcard matcher in my local fork, but will roll back if there is some reason for this.
I try to run example4 and it said that it will enumerate the text part of the email. However, the output is just plain/text...
But it did not give out the content of the email...and I cannot get that through every API you provide.
How could I get that???
Cloned the last version with git, ran cmake and got many setup errors.
There's no way to configure it without modifying the CMakeLists.txt file.
There's no way to tell it that TLS is handled by openssl.
Created a vs2010 solution but got lot of C++ errors.
I gave up.
Don't use "quoted-printable" encoding for 7 bit mails in the first place.
I have the library connecting/disconnecting to multiple stores via IMAP in a continuous loop and every time 4 bytes are added to memory. Here is some code you can use to replicate the issue; it's nothing more than a basic connection and disconnection in a simple loop. Either this is a bug or I'm overlooking some form of destructor that the examples and documentation neglect to mention.
vmime::ref <vmime::net::store> st;
vmime::ref <vmime::net::folder> f;
vmime::platform::setHandler<vmime::platforms::posix::posixHandler>();
static vmime::ref <vmime::net::session> g_session = vmime::create <vmime::net::session>();
while(1){
stringstream url_string;
url_string<<"imap://blah:blah";
cout << url_string.str() << endl;
vmime::utility::url url(url_string.str());
st = g_session->getStore(url);
st->connect();
st->disconnect();
}
Not sure about non-MinGW DLL builds, but it doesn't make sense to add bin Libs in libvmime.pc
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c636888..e479efc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -296,9 +296,6 @@ SET(VMIME_PKGCONFIG_REQUIRES "")
IF(${UNIX})
SET(libdir ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
ENDIF(${UNIX})
-IF(${WIN32})
SET(libdir ${CMAKE_INSTALL_PREFIX}/bin)
Following instructions:
cmake -G "Unix Makefiles"
make
from version of vmime in head (as of today -- 29d1be2 is the last commit)
fails with:
.../vmime/constants.hpp:48:49: error: expected unqualified-id before 'const'
.../vmime/constants.hpp:48:49: error: expected initializer before 'const'
same for all following lines. In constants.hpp, if I change:
extern const string::value_type* VMIME_EXPORT const TEXT;
into:
extern const string::value_type* const TEXT VMIME_EXPORT;
it works (note the position of VMIME_EXPORT, end of line).
By tracking down the value of VMIME_EXPORT on my system, it looks like it comes from here (note the "HERE!!" comment):
#ifdef VMIME_STATIC
# define VMIME_EXPORT
# define VMIME_NO_EXPORT
#else
# ifndef VMIME_EXPORT
# ifdef vmime_EXPORTS
/* We are building this library */
# define VMIME_EXPORT __attribute__((visibility("default"))) // HERE!!!
# else
/* We are using this library */
# define VMIME_EXPORT __attribute__((visibility("default")))
# endif
# endif
so, VMIME_STATIC is undefined, VMIME_EXPORT is not defined, and vmime_EXPORTS is defined. Weird that regardless of this last check, the result is the same.
this is a Debian GNU system, with:
$ g++ --version
g++-4.7.real (Debian 4.7.3-4) 4.7.3
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ cmake --version
cmake version 2.8.9
Compiling windowsSocket.cpp on mingw (mingw.org) fails because of missing declaration for function inet_ntop(). One workaround is to just add the missing declaration. The implementation is in libws2_32. Another possibility is to use gnulib's implementation, which is what gnutls apparently does.
When parsing an IMAP message, a type check exception is triggered because the checked type is mailboxList, and the type checker expects addressList or a subclass.
Exception is thrown in headerField.cpp, line 348, function 'setValue'
Called from IMAPMessage.cpp, line 466, function 'processFetchResponse'
The gcc compiler does not define WIN32 when -ansi is used. MinGW w32api version 3 defines WIN32, but this is considered to be a bug by the MinGW. Version 4 does not define WIN32.
Gcc does define _WIN32 (with or without -ansi).
https://sourceforge.net/p/mingw/bugs/1987/
./src/security/cert/openssl/X509Certificate_OpenSSL.cpp:51:#ifdef WIN32
./src/security/cert/openssl/X509Certificate_OpenSSL.cpp:387:#ifdef WIN32
./CMakeLists.txt:748:IF(WIN32)
./CMakeLists.txt:768:IF(WIN32)
./vmime/constants.hpp:34:#ifdef WIN32
./cmake/FindGSasl.cmake:24:IF (NOT WIN32)
./cmake/FindGSasl.cmake:30:ENDIF (NOT WIN32)
./CMakeFiles/CompilerIdC/CMakeCCompilerId.c:198:#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
./CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp:186:#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
0d6aef8 replaces strcpy with strcpy_s which is not provided by MinGW.
I am trying to update my vmime implementation from 0.7.1 to 0.9.1.
I am having no luck finding good examples of extracting the attachments from an email... and this is the code below that used to work in 0.7.1:
// NOTE: this->msg is a vmime::message* msg;
// see if the body IS an attachment
const vmime::header& hdr = *this->msg->getHeader();
const vmime::body& bdy = *this->msg->getBody();
bool isAttachment = false;
vmime::defaultParameter* def_param = NULL;
vmime::contentTypeField* ctf = NULL;
// this will get the name field for the particular body part
try
{
ctf = dynamic_cast <vmime::contentTypeField*> (hdr.findField(vmime::fields::CONTENT_TYPE));
def_param = dynamic_cast <vmime::defaultParameter*>(ctf->getParameter("name"));
log_debug2("Content_type->name = [%s]", def_param->getValue().getBuffer().c_str());
}
catch (vmime::exceptions::no_such_field)
{
log_debug1("no Content Type field");
def_param = NULL;
}
try
{
const vmime::contentDispositionField& cdf = dynamic_cast<vmime::contentDispositionField&>
(*hdr.findField(vmime::fields::CONTENT_DISPOSITION));
How should I be doing this in 0.9.1?
Thanks
Joe Johnson
EXTRACT_ALL
EXTRACT_PRIVATE
EXTRACT_STATIC
EXTRACT_LOCAL_CLASSES
EXTRACT_LOCAL_METHODS
EXTRACT_ANON_NSPACES
In summary, I am using VMIME v0.9.1 for a C++ website generator project, and I love it's design and structure. However, I am saddened that so much of the source code is NOT Doxygen documented, and, while the "vmime-book.pdf" helps a lot, it is far from enough to understand many of the undocumented classes, members and methods of the VMIME library.
Thanks for a great libary! Keep up the great work helping us all in the open source community providing quality free access source.
Best regards,
Tom Straub
BigNM LLC
From RFC-3798:
" The envelope sender address (i.e., SMTP MAIL FROM) of the MDN MUST be null (<>), specifying that no Delivery Status Notification messages or other messages indicating successful or unsuccessful delivery are to be sent in response to an MDN. "
Modify SMTPTransport::send() to send an empty "MAIL FROM <>" when sending a MDN (identifiable by top-level MIME content-type being "multipart/report" and report-type="disposition-notification".
The library got removed from Debian because of an ABI change.
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=706332
It would be nice to fix the problem so that they can add it back.
Although CMakeLists.txt sets up VMIME_PKGCONFIG_LIBS VMIME_PKGCONFIG_REQUIRES and these appear in libvime.pc.in, when building static libvmime, libvmime.pc is missing the expected values.
And shouldn't these actually appear in the .private variants, for example:
Requires.private: gnutls libgsasl
Libs.private: -liconv -lws2_32
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.