mail küldése c vagy c++ -ból

 ( kaltsi | 2008. december 1., hétfő - 12:35 )

Keresgéltem, de nem találtam igazán jó megoldást arra, hogy hogyan tudok mail-t küldeni C-ből. Mail-relay-en keresztül szeretném a leveleket küldeni, postfix beállításait figyelembe véve vagy azon keresztül.
Mivel ilyet még nem csináltam, lehet sok hülyeséget írtam. :)

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

man sendmail
man mail
smtp.cpp, de alap lehet egy c-s smtp klienshez.
Alapvetoen ketto dolog kell neked: meg kell komponalnod a levleet, es szabvany smtp protokollon at elkuldeni. Ebbol a komponalast szinte biztos, hogy neked kell csinalni, a kuldest meg csinalhatod magad, vagy ott a sendmail binaris.
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

mime-construct

pl. igy:

char buf[1024];
FILE *p;
char *b = "level szovege...\n"

sprintf(buf, "/usr/bin/mail -s \"%s\" %s", "test mail", "cimzett@cime");
p = popen(buf, "w");
write(fileno(p), b, strlen(b));
pclose(p);

A sendmail-t is lehet popen-elni, de akkor neked kell legyartani a
level fejlecet, az macerasabb. Es irj bele hibakezelest is.


#include
#include
#include
#include
#include

struct hostent *hl;

int main(int argc, char** argv) {
int sock;
struct sockaddr_in to;
int i;

char buffer[1024];
char msg_char;

if (argc != 4) {
fprintf(stderr, "Usage: %s to_address from_address \"subject\"\n", argv[0]);
return 1;
}

to.sin_family = AF_INET;
to.sin_port = htons(25);

hl = gethostbyname("smtp.szervered.neve.hu");
if (!hl)
{
perror("No such address!"); return -1;
}
memcpy(&to.sin_addr.s_addr,hl->h_addr,hl->h_length);

sock = socket(AF_INET, SOCK_STREAM, 0);
connect(sock, (struct sockaddr*) &to, sizeof(to));

read(sock,buffer,1024);

sprintf(buffer,"HELO sajat.geped.neve.hu \r\n");
write(sock, buffer, strlen(buffer) );
read(sock,buffer,1024);

sprintf(buffer,"MAIL FROM: <%s> \r\n",argv[2]);
write(sock, buffer, strlen(buffer) );
read(sock,buffer,1024);

sprintf(buffer,"RCPT TO: <%s> \r\n",argv[1]);
write(sock, buffer, strlen(buffer) );
read(sock,buffer,1024);

sprintf(buffer,"DATA \r\n");
write(sock, buffer, strlen(buffer) );
read(sock,buffer,1024);

sprintf(buffer,"Subject: %s \r\n",argv[3]);
write(sock,buffer,strlen(buffer) );

while ( (msg_char = getchar()) != EOF )
write(sock, &msg_char , 1);

write(sock,"\r\n.\r\n",5);

sprintf(buffer,"QUIT \r\n");
write(sock, buffer, strlen(buffer) );
read(sock,buffer,1024);

close(sock);
return 0;
}

A parancssorbol veszi a parametereket, lasd hibauzi. Stdin-rol veszi a level torzset.

Szerk.: postfix beallitasai le vannak sz@rva, bocsi. :)

nagyon köszi a példákat és a segítségeket, holnap kipróbálom a dolgokat és megírom hogy sikerült.

ja, ami lemaradt include: stdio.h, unistd.h, netdb.h, sys/socket.h, netinet/in.h

Neked is: &lt; es &gt;

Trey: telleg kellene valamit kezdeni ezzel, igy nem jo
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Köszi. Írtam köréje code-taget, nagyobb hatásra számítottam, mint ami lett belőle.

sprintf(buffer,"MAIL FROM: <%s> \r\n",argv[2]);

Ott figyel a stack overflow! ;)

--
Fontos feladatot soha ne bizz olyan gepre, amit egyedul is fel tudsz emelni!

Milyen igazad van. Nekem fel sem tűnt.

Elvileg vsprintf-et kellene használni, vagy előre kiszámolni, hogy mekkora puffer kellene. A C/C++-ban az a rossz, hogy ilyen marhaságokon kell az időd 90%-ában gondolkozni, ahelyett, hogy programoznál.

Persze itt az std::string-et nyugodtan lehetne használni. Nem lassabb, mint a mail server-rel a kapcsolatot felépíteni.

:-)

En snprintf-fet szoko hasznalni, es saccra meg lehet becsulni, hogy az adott kontextusban mekkora puffer fog kelleni. Sot, ebben a konkret esetben ki is lehet szamolni strlen meg egy kis matek felhasznalasaval.
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Jol irta hrgy84 az snprintf()-et. Nem kell ide semmi "90% ezen gondolkozas", egyszeruen meg kell szokni, hogy a biztonsagos fuggvenyeket hasznald.

Amugy erdemes lenne a read() utan megnezni, hogy megis mit kuldott vissza a postfix - ha nem akarsz elvesziteni levelet...

SPAMtelenul - POP3 spamszuro szolgaltatas

Mivel az e-mail küldés nem része egyik C szabványnak se, így csak a fentebb említett különböző platrform specifikus megoldások közül válogathatsz:

- használasz valami SMTP API-t
- fork+execve sendmailre
- socket-el megnyitod az SMTP portot, nem egy bonyi protokoll

--
The Net is indeed vast and infinite...
http://gablog.eu

socket-el megnyitod az SMTP portot, nem egy bonyi protokoll
igen, csak amint az smtp szerver nem megbizhato helyre kerul (azaz minden csak nem lokalhoszt), akkor nem is a proto bonyolultsaga fogja megneheziteni a dolgot, hanem az, hogy az osszes hulye hibalehetoseget, flow controlt es timeout-ot lekezeld.

Ilyen ertelemben tenyleg egyszerubb egy popen() vagy ha ketiranyu adatforgalom kell vmiert (mondjuk nem pont itt, ugy altalaban), akkor for(), execve(), elotte kezzel nehany pipe() es/vagy dup2().

Illetve az is lehet hogy nem is az smtp bonyolultsaga lesz a szuk keresztmetszet, hanem hogy maga't a leveltorzset osszeallitsd (encoding, attachmentek, stb). Ez a mime-construct nevu progi tunt ilyen szempontbol a legsokoldalubbnak nekem, meg regebben (azota persze lehet hogy mas jo megoldas is megjelent). Ja es ez me'g el is kuldi a levelet ;)

Megmozgattad a fantaziam, lehet hogy ha lesz egy kis idom, osszerakok egy kis smtp kuldo libet.
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Egesz jol haladok, mar van level, meg kapcsolat, mar csak a levelkuldest kellene leprogramozni. Ha az meglesz, kilinkelem a git repot hozza.
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

http://libsmtp.berlios.de/

"libsmtp enables developers to send mail directly via SMTP from a program."

1) ez miert nem jelent meg nekem google-ba?
2) glib fuggo...
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Én "libsmtp"-t írtam be, és ez jött ki első találatnak. :-)

bár ez c++ ...