email program.........

2

/*24age*/

well i got this from net itself though it is not working....pls try it
yourself..and tell me y the error message....

pls...include the email address....which i have left .....

vijesh

program
************************************************************


#include <stdio.h>
#include <io.h>

int rc;
char buf[256];

//#define LINUX /* define this if you are on linux */
//#define WIN32 /* define this if you are on windows */

#ifdef WIN32
# include "io.h"
# include "winsock2.h" /* WSAGetLastError, WSAStartUp */
# define snprintf _snprintf
#endif

#ifdef LINUX
# include <netdb.h> /* gethostbyname */
# include <netinet/in.h> /* htons */
# include <sys/socket.h>
#endif

#pragma comment(lib, "wsock32.lib")

static void sendmail_write(const int sock,const char *str,const char
*arg, bool reply)
{
char buf[4096];

if (arg != NULL)
snprintf(buf, sizeof(buf), str, arg);
else
snprintf(buf, sizeof(buf), str);

send(sock, buf, strlen(buf), 0);

if(reply)
{
if((rc = recv(sock, buf, sizeof(buf) - 1, 0)) == -1)
{
perror("recv");
printf("%s", "ERROR");
}
else
{
buf[rc] = 0;
printf("%s", buf);
}
}
}

static int sendmail(const char *from,const char *to,const char
*subject,const char *body, const char *hostname,const int port)
{
struct hostent *host;
struct sockaddr_in saddr_in;
int sock = 0;

#ifdef WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
return -1;
}
#endif

sock = socket(AF_INET, SOCK_STREAM, 0);
host = gethostbyname(hostname);

saddr_in.sin_family = AF_INET;
saddr_in.sin_port = htons((u_short)port);
saddr_in.sin_addr.s_addr = 0;

memcpy((char*)&(saddr_in.sin_addr), host->h_addr, host->h_length);

if(connect(sock, (struct sockaddr*)&saddr_in, sizeof(saddr_in)) == -1)
{
return -2;
}

char buf[4096];

//read out server welcome message
if((rc = recv(sock, buf, sizeof(buf) - 1, 0)) == -1)
{
perror("recv");
printf("%s", "ERROR");
}
else
{
buf[rc] = 0;
printf("%s", buf);
}


sendmail_write(sock, "helo %s\r\n", from, true); // greeting
sendmail_write(sock, "mail from: %s\r\n", from, true); // from
sendmail_write(sock, "rcpt to: %s\r\n", to, true); // to
sendmail_write(sock, "data\r\n", NULL, true); // begin data
//printf("%s", "\nWe are after quit command");

// next comes mail headers
sendmail_write(sock, "From: %s\r\n", from, false);
sendmail_write(sock, "To: %s\r\n", to, false);
sendmail_write(sock, "Subject: %s\r\n", subject, false);
sendmail_write(sock, "Date: 6/6/6\r\n", NULL, false);

sendmail_write(sock, "\r\n", NULL, false);

sendmail_write(sock, "%s\r\n", body, false); // data

sendmail_write(sock, ".\r\n", NULL, true); // end data

sendmail_write(sock, "QUIT", NULL, false); // terminate
//printf("%s", "\nWe are after quit command"); //never even gets to
this line

#ifdef WIN32
closesocket(sock);
#else
close(sock);
#endif

return 0;
}

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



int ret = sendmail(
"(e-mail address removed)", /* from */
"(e-mail address removed)", /* to */
"Subject", /* subject */
"body", /* body */
"vij", /* hostname */
25 /* port */
);

if (ret != 0)
fprintf(stderr, "Failed to send mail (code: %i).\n", ret);
else
fprintf(stdout, "Mail successfully sent.\n");

return ret;
}
 
T

Tom St Denis

/*24age*/ said:
well i got this from net itself though it is not working....pls try it
yourself..and tell me y the error message....

pls...include the email address....which i have left .....

why......not......um.......use.........English?

I can see mispelling words but replacing words w shrthnd Z just anying.
#include <stdio.h>
#include <io.h>

int rc;
char buf[256];

useless globals.
//#define LINUX /* define this if you are on linux */
//#define WIN32 /* define this if you are on windows */

What about BSD, QNX, UNIX and MacOS?
#ifdef WIN32
# include "io.h"
# include "winsock2.h" /* WSAGetLastError, WSAStartUp */
# define snprintf _snprintf
#endif

Why are these "" headers?
#pragma comment(lib, "wsock32.lib")

WTF is this for? Just add wsock32.lib to your linker line.
send(sock, buf, strlen(buf), 0);

Doesn't check the return value.
if(reply)
{
if((rc = recv(sock, buf, sizeof(buf) - 1, 0)) == -1)

You don't zero the buffer first. So say it held

"HELLO\0" and you recv 3 bytes, say "THE" then you get THELO\0 as your
string.
perror("recv");
printf("%s", "ERROR");

um... why not printf("ERROR") ?
buf[rc] = 0;
printf("%s", buf);

Ok, so you did clear the stirng good. Note that rc=0 is possible
indicating an orderly shutdown [see man 2 recv]
sock = socket(AF_INET, SOCK_STREAM, 0);
host = gethostbyname(hostname);

No error detection. AF_INET is also deprecated isn't it? PF_INET is
more preferable.
char buf[4096];

Declaring arrays in the middle of your C code? ...

<snip repeated function calls>

Hint, make an array of a structure, use a damn for loop.
return ret;

return values should be EXIT_SUCCESS or EXIT_FAILURE.
Tom
 
J

Jack Klein

well i got this from net itself though it is not working....pls try it
yourself..and tell me y the error message....

pls...include the email address....which i have left .....

vijesh

program
************************************************************


#include <stdio.h>
#include <io.h>

int rc;
char buf[256];

//#define LINUX /* define this if you are on linux */
//#define WIN32 /* define this if you are on windows */

#ifdef WIN32
# include "io.h"
# include "winsock2.h" /* WSAGetLastError, WSAStartUp */
# define snprintf _snprintf
#endif

#ifdef LINUX
# include <netdb.h> /* gethostbyname */
# include <netinet/in.h> /* htons */
# include <sys/socket.h>
#endif

None of this is part of the C language. None of the headers except
<stdio.h> are part of standard C. Try a Windows group and a Linux
group, after you learn how to write a proper post.
 
D

Dave Thompson

Aside: you are using // comments and declare-after-statement, which
are only standard in C99 but are available before that in GCC which is
available on both the platforms you mention. Your code could easily
avoid these features and be more widely portable. Although we don't
have a crying need for more portable spamming tools.
#include <stdio.h>
#include <io.h>
io.h is not a Standard C header, and not needed AFAICS anyway.
int rc;
char buf[256];
These don't need to be globals.
//#define LINUX /* define this if you are on linux */
//#define WIN32 /* define this if you are on windows */

#ifdef WIN32
# include "io.h"
# include "winsock2.h" /* WSAGetLastError, WSAStartUp */

also all the other socket+net calls. And you don't actually use
WSAGetLastError. If you want to report specific errors, which I
recommend, you need to use WSAGetLastError() on Windows but on Unix
errno except for netdb routines h_errno. To avoid clutter all over the
place, hide these in a macro or two or encapsulate in routine(s).
# define snprintf _snprintf
#endif

#ifdef LINUX
# include <netdb.h> /* gethostbyname */
# include <netinet/in.h> /* htons */
# include <sys/socket.h>
#endif

#pragma comment(lib, "wsock32.lib")

static void sendmail_write(const int sock,const char *str,const char
*arg, bool reply)

Here and again below 'int' is not the correct type on Windows; use
SOCKET. I prefer to use it always and typedef to int for Unix; it's
slightly more selfdocumenting even there.
{
char buf[4096];

if (arg != NULL)
snprintf(buf, sizeof(buf), str, arg);
else
snprintf(buf, sizeof(buf), str);
You don't need to make two different calls here; if the format string
does not include a %s (or other) specifier, the extra null-pointer
argument is (guaranteed) safely ignored.
send(sock, buf, strlen(buf), 0);
Should check for and handle error (although not too likely).
if(reply)
{
if((rc = recv(sock, buf, sizeof(buf) - 1, 0)) == -1)
{
perror("recv");

perror is useless for winsock; per above use WSAGetLastError() at
least; and strerror() doesn't normally work for winsock errors, so if
you want text you have to do it yourself or use more Windows-specific
stuff which is a nuisance and even further offtopic.
printf("%s", "ERROR");
}
else
{
buf[rc] = 0;
printf("%s", buf);
}
}
}

static int sendmail(const char *from,const char *to,const char
*subject,const char *body, const char *hostname,const int port)
{
struct hostent *host;
struct sockaddr_in saddr_in;
int sock = 0;

#ifdef WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
return -1;
}
#endif

sock = socket(AF_INET, SOCK_STREAM, 0);
host = gethostbyname(hostname);
Should check host is valid (nonnull) before using it. Technically
should check sock is valid also, but that's much less likely to fail.
saddr_in.sin_family = AF_INET;
saddr_in.sin_port = htons((u_short)port);
saddr_in.sin_addr.s_addr = 0;

memcpy((char*)&(saddr_in.sin_addr), host->h_addr, host->h_length);
Don't need the cast there.
if(connect(sock, (struct sockaddr*)&saddr_in, sizeof(saddr_in)) == -1)

But do need that one. The sockaddr* types are actually compatible but
not declared so, hence these are among the few casts justified in
well-written C.
{
return -2;
}

char buf[4096];

//read out server welcome message
if((rc = recv(sock, buf, sizeof(buf) - 1, 0)) == -1)
{
perror("recv");
printf("%s", "ERROR");
}
else
{
buf[rc] = 0;
printf("%s", buf);
}


sendmail_write(sock, "helo %s\r\n", from, true); // greeting

HELO should specify the sending _system_ not the originating user.

Should check somewhere, perhaps in sendmail_write, for an error reply
code (other than 2xx or 1xx/3xx where applicable) and abort.

To be really really pedantic, \r and \n in C are not guaranteed to be
ASCII CR and LF as required. But then neither are other characters
like letters guaranteed to be in ASCII. A really portable solution to
this is more work than probably justified here.
sendmail_write(sock, "mail from: %s\r\n", from, true); // from
sendmail_write(sock, "rcpt to: %s\r\n", to, true); // to
sendmail_write(sock, "data\r\n", NULL, true); // begin data
//printf("%s", "\nWe are after quit command");
If that wasn't commented out it would be very misleading.
// next comes mail headers
sendmail_write(sock, "From: %s\r\n", from, false);
sendmail_write(sock, "To: %s\r\n", to, false);
sendmail_write(sock, "Subject: %s\r\n", subject, false);
sendmail_write(sock, "Date: 6/6/6\r\n", NULL, false);
That is not (and never has been) even close to a valid [2]822 format
for Date. The server is entitled to reject or bounce the message for
this reason, although I'm not sure how many actually will.
sendmail_write(sock, "\r\n", NULL, false);

sendmail_write(sock, "%s\r\n", body, false); // data

sendmail_write(sock, ".\r\n", NULL, true); // end data
Should _definitely_ check for error reply code here, before returning
to the caller and giving a very misleading output. (It is legal, and
fairly common, to give even an envelope error only after the body.)
sendmail_write(sock, "QUIT", NULL, false); // terminate
//printf("%s", "\nWe are after quit command"); //never even gets to
this line
It should, unless you have ignored some error earlier, or your mail
server (or proxy therefor or something) is defective.

Assuming the // comment presumably broken in posting is fixed.
#ifdef WIN32
closesocket(sock);
#else
close(sock);
#endif

return 0;
}

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



int ret = sendmail(
"(e-mail address removed)", /* from */
"(e-mail address removed)", /* to */
"Subject", /* subject */
"body", /* body */
"vij", /* hostname */

Obviously this wouldn't be the correct mailhost in a real situation;
you need to lookup the MX records, check precedence, recognize
transient and nontransient errors and schedule retries, etc. But as a
test and assuming it is a resolvable reachable host it should work.
25 /* port */
);

if (ret != 0)
fprintf(stderr, "Failed to send mail (code: %i).\n", ret);
else
fprintf(stdout, "Mail successfully sent.\n");

return ret;
}

- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top