Jak wysłać plik (C++)?

increase

Użytkownik
Dołączył
Lipiec 24, 2012
Posty
9
Cześć, szukam jakiegoś sposobu na wysłanie pliku w C++ (najlepiej na serwer FTP lub adres e-mail ale chętnie poznam też inne metody) za pośrednictwem internetu.
 

mto9

Użytkownik
Dołączył
Kwiecień 20, 2011
Posty
81
Sam napisałem bardzo prostą ala "bibliotekę", o to kod:
message.h
#ifndef MESSAGE_H
#define MESSAGE_H

#include <string>
#include <vector>

namespace Mto9
{

class Message
{
public:
Message(const std::string & subject = std::string(), const std::string & contents = std::string(),
std::vector<std::string> recipients = std::vector<std::string>(),
std::vector<std::string> attachments = std::vector<std::string>());

bool addAttachment(const std::string & filePath);
void addAttachments(std::vector<std::string> & v);
bool addRecipient(const std::string & e_mailAddress);
void addRecipients(std::vector<std::string> & v);
void clear();
int findAttachment(const std::string & filePath) const;
int findRecipient(const std::string & e_mailAddress) const;
std::vector<std::string> getAllAttachments() const { return attachments; }
std::vector<std::string> getAllRecipients() const { return recipients; }
std::string getContents() const { return contents; }
std::string getAttachmentAt(int index) const;
std::string getRecipientAt(int index) const;
int getAttachmentCount() const { return attachments.size(); }
int getRecipientCount() const { return recipients.size(); }
std::string getSubject() const { return subject; }
bool isReadyToSend() const;
bool removeAttachmentAt(int index);
bool removeRecipientAt(int index);
void removeAllAttachments() { attachments.clear(); }
void removeAllRecipients() { recipients.clear(); }
void setContents(const std::string & newContents) { contents = newContents; }
void setSubject(const std::string & newSubject) { subject = newSubject; }


private:
bool fileExists(const std::string & filePath) const;
bool isAlreadyUsed(const std::string & name,std::vector<std::string> & v) const;

std::vector<std::string> attachments;
std::string contents;
std::vector<std::string> recipients;
std::string subject;

};

}

#endif // MESSAGE_H

message.cpp
#include "message.h"
#include <fstream>
//#include <regex>

namespace Mto9
{

Message::Message(const std::string & subject, const std::string & contents,
std::vector<std::string> recipients, std::vector<std::string> attachments):
subject(subject),
contents(contents),
recipients(recipients),
attachments(attachments)
{

}

bool Message::addAttachment(const std::string &filePath)
{
if((!isAlreadyUsed(filePath, attachments)) && fileExists(filePath))
{
this->attachments.push_back(filePath);
return true;
}
else return false;
}

void Message::addAttachments(std::vector<std::string> &v)
{
for(int i=0; i<v.size(); i++) this->addAttachment(v);
}

bool Message::addRecipient(const std::string &e_mailAddress)
{
/* // Version for C++0x //

std::regex model("^[-!#$%&'*+/0-9=?A-Z^_a-z{|}~](\.?[-!#$%&'*+/0-9=?A-Z^_a-z{|}~])*@"
"[a-zA-Z](-?[a-zA-Z0-9])*(\.[a-zA-Z](-?[a-zA-Z0-9])*)+$");
if(std::regex_match(e_mailAddress, model) && (!isAlreadyUsed(e_mailAddress, recipients)))
{
this->recipients.push_back(e_mailAddress);
return true;
}
else return false;

*/

this->recipients.push_back(e_mailAddress);
return true;
}

void Message::addRecipients(std::vector<std::string> &v)
{
for(int i=0; i<v.size(); i++) this->addRecipient(v);
}

void Message::clear()
{
this->subject = std::string();
this->contents = std::string();
this->recipients.clear();
this->attachments.clear();
}

int Message::findRecipient(const std::string &e_mailAddress) const
{
for(int i=0; i<recipients.size(); i++) if(e_mailAddress == recipients) return i;
return -1;
}

std::string Message::getAttachmentAt(int index) const
{
if(this->attachments.size() > index) return attachments[index];
else return std::string();
}

int Message::findAttachment(const std::string &filePath) const
{
for(int i=0; i<attachments.size(); i++) if(filePath == attachments) return i;
return -1;
}

std::string Message::getRecipientAt(int index) const
{
if(this->recipients.size() > index) return this->recipients[index];
else return std::string();
}

bool Message::isReadyToSend() const
{
if((!this->subject.empty()) && (!this->contents.empty()) && this->recipients.size() > 0) return true;
else return false;
}

bool Message::removeAttachmentAt(int index)
{
if(this->attachments.size() > index)
{
this->attachments.erase(attachments.begin() + index);
return true;
}
else return false;
}

bool Message::removeRecipientAt(int index)
{
if(this->recipients.size() > index)
{
this->recipients.erase(recipients.begin() + index);
return true;
}
else return false;
}

bool Message::fileExists(const std::string &filePath) const
{
std::ifstream file;
file.open(filePath.c_str());
if(file.is_open())
{
file.close();
return true;
}
else return false;
}

bool Message::isAlreadyUsed(const std::string & name, std::vector<std::string> & v) const
{
for(int i=0; i<v.size(); i++) if(name == v) return true;
return false;
}

}


smtptransport.h
#ifndef SMTPTRANSPORT_H
#define SMTPTRANSPORT_H

#include "message.h"

namespace Mto9
{

class SMTPTransport
{
public:
//enum Encryption {Lack, SSL, TLS};

SMTPTransport(const std::string & senderAddress = std::string(),
const std::string & senderPassword = std::string(),
const std::string & hostAddress = std::string(),
unsigned port = 465/*, Encryption encryption = SSL*/);

//Encryption getEncryption() const { return encryption; }
std::string getHostAddress() const { return hostAddress; }
std::string getLastError() const { return lastError; }
unsigned getPort() const { return port; }
std::string getSenderAddress() const { return senderAddress; }
std::string getSenderPassword() const { return senderPassword; }
bool isConfigured() const;
bool send(Message & message);
//void setEncryption(Encryption newEncryption) { encryption = newEncryption; }
void setHostAddress(const std::string & newHostAddress) { hostAddress = newHostAddress; }
void setPort(unsigned newPort) { port = newPort; }
bool setSenderAddress(const std::string & e_mailAddress);
void setSenderPassword(const std::string & password) { senderPassword = password; }

private:
std::string getFileName(const std::string & file) const { return file.substr(file.rfind('\\')+1); }
std::string getMIMEType(const std::string & file) const;
std::string readFile(const std::string & filePath) const;
std::string toBase64(const std::string & stringToEncode) const;

//Encryption encryption;
std::string hostAddress;
mutable std::string lastError;
unsigned port;
std::string senderAddress;
std::string senderPassword;

};

}

#endif // SMTPTRANSPORT_H

smtptransport.cpp
#include "smtptransport.h"
#include <fstream>
//#include <regex>
#include <sstream>
#include <streambuf>
#include <WinSock2.h>

namespace Mto9
{

SMTPTransport::SMTPTransport(const std::string & senderAddress, const std::string & senderPassword,
const std::string & hostAddress, unsigned port/*, Encryption encryption*/):
senderPassword(senderPassword),
hostAddress(hostAddress),
port(port)/*,
encryption(encryption)*/
{
setSenderAddress(senderAddress);
}

inline bool SMTPTransport::isConfigured() const
{
return (!(this->senderAddress.empty()) && !(this->senderPassword.empty()) && !(this->hostAddress.empty()));
}

bool SMTPTransport::send(Message &message)
{
if(!message.isReadyToSend())
{
this->lastError = "Message is not ready to send";
return false;
}
if(!(this->isConfigured()))
{
this->lastError = "SMTPTransport is not configured";
return false;
}

WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);

LPHOSTENT hostEntry = gethostbyname(this->hostAddress.c_str());
if(hostEntry == 0)
{
this->lastError = "gethostbyname returns a null pointer";
WSACleanup();
return false;
}
SOCKADDR_IN saddr;
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

const unsigned sizeBuffer = 1024;
char buffer[sizeBuffer];
std::string tempString, tempString2;

saddr.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);
saddr.sin_family = AF_INET;
saddr.sin_port = htons(this->port);

if(connect(sock, (sockaddr*)&saddr, sizeof(sockaddr)) == SOCKET_ERROR)
{
this->lastError = "SOCKET_ERROR";
WSACleanup();
return false;
}

recv(sock, buffer, sizeBuffer - 1, 0);
if(buffer[0] == '5' || buffer[0] == '4')
{
this->lastError = buffer;
closesocket(sock);
WSACleanup();
return false;
}

tempString = "EHLO " + this->hostAddress + "\r\n";
::send(sock, tempString.c_str(), tempString.size(), 0);
recv(sock, buffer, sizeBuffer - 1, 0);
if(buffer[0] == '5' || buffer[0] == '4')
{
this->lastError = buffer;
closesocket(sock);
WSACleanup();
return false;
}

::send(sock, "AUTH LOGIN\r\n", 12, 0);
recv(sock, buffer, sizeBuffer - 1, 0);
if(buffer[0] == '5' || buffer[0] == '4')
{
this->lastError = buffer;
closesocket(sock);
WSACleanup();
return false;
}

tempString = this->toBase64(this->senderAddress) + "\r\n";
::send(sock, tempString.c_str(), tempString.size(), 0);
recv(sock, buffer, sizeBuffer - 1, 0);
if(buffer[0] == '5' || buffer[0] == '4')
{
this->lastError = buffer;
closesocket(sock);
WSACleanup();
return false;
}

tempString = this->toBase64(this->senderPassword) + "\r\n";
::send(sock, tempString.c_str(), tempString.size(), 0);
recv(sock, buffer, sizeBuffer - 1, 0);
if(buffer[0] == '5' || buffer[0] == '4')
{
this->lastError = buffer;
closesocket(sock);
WSACleanup();
return false;
}

tempString = "MAIL FROM: <" + this->senderAddress + ">\r\n";
::send(sock, tempString.c_str(), tempString.size(), 0);
recv(sock, buffer, sizeBuffer - 1, 0);
if(buffer[0] == '5' || buffer[0] == '4')
{
this->lastError = buffer;
closesocket(sock);
WSACleanup();
return false;
}

for(int i=0; i<message.getRecipientCount(); i++)
{
tempString = "RCPT TO: <" + message.getRecipientAt(i) + ">\r\n";
tempString2 += (message.getRecipientAt(i) + ", ");
::send(sock, tempString.c_str(), tempString.size(), 0);
recv(sock, buffer, sizeBuffer - 1, 0);
if(buffer[0] == '5' || buffer[0] == '4')
{
this->lastError = buffer;
closesocket(sock);
WSACleanup();
return false;
}
}

::send(sock, "DATA\r\n", 6, 0);
recv(sock, buffer, sizeBuffer - 1, 0);
if(buffer[0] == '5' || buffer[0] == '4')
{
this->lastError = buffer;
closesocket(sock);
WSACleanup();
return false;
}

::send(sock, "MIME-Version: 1.0\r\n", 19, 0);

tempString = "Subject: =?Windows-1250?B?" + this->toBase64(message.getSubject()) + "?=\r\n";
::send(sock, tempString.c_str(), tempString.size(), 0);

tempString = "From: " + this->senderAddress + "\r\n";
::send(sock, tempString.c_str(), tempString.size(), 0);

tempString = "To: " + tempString2 + "\r\n";
::send(sock, tempString.c_str(), tempString.size(), 0);

if(message.getAttachmentCount() > 0)
{
::send(sock, "Content-Type: multipart/mixed; boundary=00newline9\r\n\r\n", 54, 0);
::send(sock, "--00newline9\r\n", 14, 0);
}

::send(sock, "Content-Type: text/plain; charset=Windows-1250\r\n", 48, 0);
::send(sock, "Content-Transfer-Encoding: base64\r\n\r\n", 37, 0);

tempString = this->toBase64(message.getContents()) + "\r\n\r\n";
::send(sock, tempString.c_str(), tempString.size(), 0);

if(message.getAttachmentCount() > 0)
{
for(int i=0; i<message.getAttachmentCount(); i++)
{
::send(sock, "--00newline9\r\n", 14, 0);

tempString = "Content-Type: " + this->getMIMEType(message.getAttachmentAt(i)) +
"; name=\"" + this->getFileName(message.getAttachmentAt(i)) + "\"\r\n";
::send(sock, tempString.c_str(), tempString.size(), 0);

tempString = "Content-Disposition: attachment; filename=\"" + getFileName(message.getAttachmentAt(i)) + "\"\r\n";
::send(sock, tempString.c_str(), tempString.size(), 0);

::send(sock, "Content-Transfer-Encoding: base64\r\n\r\n", 37, 0);

tempString = this->toBase64(this->readFile(message.getAttachmentAt(i))) + "\r\n";
::send(sock, tempString.c_str(), tempString.size(), 0);
}

::send(sock, "--00newline9--\r\n", 16, 0);
}

::send(sock, ".\r\n", 3, 0);
recv(sock, buffer, sizeBuffer - 1, 0);
if(buffer[0] == '5' || buffer[0] == '4')
{
this->lastError = buffer;
closesocket(sock);
WSACleanup();
return false;
}

::send(sock, "QUIT\r\n", 6, 0);
recv(sock, buffer, sizeBuffer - 1, 0);

closesocket(sock);
WSACleanup();
return true;
}

bool SMTPTransport::setSenderAddress(const std::string &e_mailAddress)
{
/* // Version for C++0x //

std::regex model("^[-!#$%&'*+/0-9=?A-Z^_a-z{|}~](\.?[-!#$%&'*+/0-9=?A-Z^_a-z{|}~])*@"
"[a-zA-Z](-?[a-zA-Z0-9])*(\.[a-zA-Z](-?[a-zA-Z0-9])*)+$");
if(std::regex_match(e_mailAddress, model))
{
this->senderAddress = e_mailAddress;
return true;
}
else return false;

*/

this->senderAddress = e_mailAddress;
return true;
}

std::string SMTPTransport::getMIMEType(const std::string &file) const
{
std::string enlargement = file.substr(file.rfind('.')+1);

/* The most popular types of files */
if(enlargement=="zip") return "application/zip";
if(enlargement=="rar") return "application/rar";
if(enlargement=="mp3") return "audio/mpeg";
if(enlargement=="pdf") return "application/pdf";
if(enlargement=="html") return "text/html";
if(enlargement=="htm") return "text/html";
if(enlargement=="png") return "image/png";
if(enlargement=="gif") return "image/gif";
if(enlargement=="bmp") return "image/bmp";
if(enlargement=="jpeg") return "image/jpeg";
if(enlargement=="jpg") return "image/jpeg";
if(enlargement=="pps") return "application/vnd.ms-powerpoint";
if(enlargement=="ppt") return "application/vnd.ms-powerpoint";
if(enlargement=="pptx") return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
if(enlargement=="xls") return "application/vnd.ms-excel";
if(enlargement=="xlsx") return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
if(enlargement=="txt") return "text/plain";
if(enlargement=="doc") return "application/msword";
if(enlargement=="docx") return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
if(enlargement=="avi") return "video/x-msvideo";
if(enlargement=="mov") return "video/quicktime";
if(enlargement=="wmv") return "video/x-ms-wmv";
if(enlargement=="mpeg") return "video/mpeg";
if(enlargement=="mpg") return "video/mpeg";
if(enlargement=="wma") return "audio/x-ms-wma";
/* Graphic files */
if(enlargement=="jpe") return "image/jpeg";
if(enlargement=="ico") return "image/x-icon";
if(enlargement=="psd") return "application/photoshop";
if(enlargement=="tif") return "image/tiff";
if(enlargement=="tiff") return "image/tiff";
if(enlargement=="xpm") return "image/x-xpixmap";
if(enlargement=="svg") return "image/svg+xml";
if(enlargement=="swf") return "application/x-shockwave-flash";
if(enlargement=="eps") return "application/postscript";
/* Audio files */
if(enlargement=="ra") return "audio/x-realaudio";
if(enlargement=="rm") return "audio/x-pn-realaudio";
if(enlargement=="ram") return "audio/x-pn-realaudio";
if(enlargement=="wav") return "audio/x-wav";
if(enlargement=="mid") return "audio/midi";
if(enlargement=="midi") return "audio/midi";
if(enlargement=="aif") return "audio/x-aiff";
if(enlargement=="aiff") return "audio/x-aiff";
if(enlargement=="aifc") return "audio/x-aiff";
if(enlargement=="mp2") return "audio/mpeg";
/* Video files */
if(enlargement=="mp4") return "video/mp4";
if(enlargement=="mpe") return "video/mpeg";
if(enlargement=="ogv") return "video/ogg";
if(enlargement=="qt") return "video/quicktime";
if(enlargement=="asf") return "video/x-ms-asf";
/* Text documents */
if(enlargement=="odt") return "application/vnd.oasis.opendocument.text";
if(enlargement=="ott") return "application/vnd.oasis.opendocument.text-template";
if(enlargement=="pages")return "application/x-iwork-pages-sffpages";
if(enlargement=="rtf") return "application/rtf";
if(enlargement=="sxw") return "application/vnd.sun.xml.writer";
/* Spreadsheets */
if(enlargement=="csv") return "text/csv";
if(enlargement=="ods") return "application/vnd.oasis.opendocument.spreadsheet";
if(enlargement=="ots") return "application/vnd.oasis.opendocument.spreadsheet-template";
if(enlargement=="sxc") return "application/vnd.sun.xml.calc";
/* Multimedia presentations */
if(enlargement=="ppsx") return "application/vnd.openxmlformats-officedocument.presentationml.slideshow";
if(enlargement=="odp") return "application/vnd.oasis.opendocument.presentation";
if(enlargement=="otp") return "application/vnd.oasis.opendocument.presentation-template";
if(enlargement=="sxi") return "application/vnd.sun.xml.impress";
/* Archives */
if(enlargement=="tar") return "application/x-tar";
if(enlargement=="tgz") return "application/x-gzip";
/* Other */
if(enlargement=="xml") return "text/xml";
if(enlargement=="php") return "application/x-httpd-php";
if(enlargement=="cpp") return "text/x-c++src";
if(enlargement=="c") return "text/x-csrc";
if(enlargement=="js") return "application/x-javascript";

return "application/octet-stream";
}

std::string SMTPTransport::readFile(const std::string &filePath) const
{
std::ifstream file(filePath.c_str(), std::ios::binary);
std::stringstream buffer;
buffer << file.rdbuf();
return buffer.str();
}

std::string SMTPTransport::toBase64(const std::string &stringToEncode) const
{
static const std::string base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";

std::string result;
unsigned size = stringToEncode.size();
int i=0, j=0, index=0;
unsigned char charArrary3[3];
unsigned char charArrary4[4];

while(size--)
{
charArrary3[i++] = stringToEncode[index++];
if(i == 3)
{
charArrary4[0] = (charArrary3[0] & 0xfc) >> 2;
charArrary4[1] = ((charArrary3[0] & 0x03) << 4) + ((charArrary3[1] & 0xf0) >> 4);
charArrary4[2] = ((charArrary3[1] & 0x0f) << 2) + ((charArrary3[2] & 0xc0) >> 6);
charArrary4[3] = charArrary3[2] & 0x3f;

for(i=0; i<4; i++) result += base64Chars[charArrary4];
i = 0;
}
}

if(i)
{
for(j=i; j<3; j++) charArrary3[j] = '\0';
charArrary4[0] = (charArrary3[0] & 0xfc) >> 2;
charArrary4[1] = ((charArrary3[0] & 0x03) << 4) + ((charArrary3[1] & 0xf0) >> 4);
charArrary4[2] = ((charArrary3[1] & 0x0f) << 2) + ((charArrary3[2] & 0xc0) >> 6);
charArrary4[3] = charArrary3[2] & 0x3f;

for(j=0; j<i+1; j++) result += base64Chars[charArrary4[j]];

while(i++ < 3) result += '=';
}

return result;
}

}
 
Do góry Bottom