473,503 Members | 6,385 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

smtp coding problem

hi, i have this code which is part of a main program, to email from
within the program a log file:

int MailIt (char *mailserver, char *emailto, char *emailfrom,
char *emailsubject, char *emailmessage) {
SOCKET sockfd;
WSADATA wsaData;
FILE *smtpfile;

#define bufsize 300
int bytes_sent; /* Sock FD */
int err;
struct hostent *host; /* info from gethostbyname */
struct sockaddr_in dest_addr; /* Host Address */
char line[1000];
char *Rec_Buf = (char*) malloc(bufsize+1);
smtpfile=fopen(SMTPLog,"a+");
if (WSAStartup(0x202,&wsaData) == SOCKET_ERROR) {
fputs("WSAStartup failed",smtpfile);
WSACleanup();
return -1;
}
if ( (host=gethostbyname(mailserver)) == NULL) {
perror("gethostbyname");
exit(1);
}
memset(&dest_addr,0,sizeof(dest_addr));
memcpy(&(dest_addr.sin_addr),host->h_addr,host->h_length);

/* Prepare dest_addr */
dest_addr.sin_family= host->h_addrtype; /* AF_INET from
gethostbyname */
dest_addr.sin_port= htons(25); /* PORT defined above */

/* Get socket */

if ((sockfd=socket(AF_INET,SOCK_STREAM,0)) < 0) {
perror("socket");
exit(1);
}
/* Connect !*/
fputs("Connecting....\n",smtpfile);

if (connect(sockfd, (struct sockaddr
*)&dest_addr,sizeof(dest_addr)) == -1){
perror("connect");
exit(1);
}
sleep(waittime);
err=recv(sockfd,Rec_Buf,bufsize,0);Rec_Buf[err] = '\0';
fputs(Rec_Buf,smtpfile);
strcpy(line,"helo me.somepalace.com\n");
fputs(line,smtpfile);
bytes_sent=send(sockfd,line,strlen(line),0);
sleep(waittime);
err=recv(sockfd,Rec_Buf,bufsize,0);Rec_Buf[err] = '\0';
fputs(Rec_Buf,smtpfile);
strcpy(line,"MAIL FROM:<");
strncat(line,emailfrom,strlen(emailfrom));
strncat(line,">\n",3);
fputs(line,smtpfile);
bytes_sent=send(sockfd,line,strlen(line),0);
sleep(waittime);
err=recv(sockfd,Rec_Buf,bufsize,0);Rec_Buf[err] = '\0';
fputs(Rec_Buf,smtpfile);
strcpy(line,"RCPT TO:<");
strncat(line,emailto,strlen(emailto));
strncat(line,">\n",3);
fputs(line,smtpfile);
bytes_sent=send(sockfd,line,strlen(line),0);
sleep(waittime);
err=recv(sockfd,Rec_Buf,bufsize,0);Rec_Buf[err] = '\0';
fputs(Rec_Buf,smtpfile);
strcpy(line,"DATA\n");
fputs(line,smtpfile);
bytes_sent=send(sockfd,line,strlen(line),0);
sleep(waittime);
err=recv(sockfd,Rec_Buf,bufsize,0);Rec_Buf[err] = '\0';
fputs(Rec_Buf,smtpfile);
sleep(waittime);
strcpy(line,"To:");
strcat(line,emailto);
strcat(line,"\n");
strcat(line,"From:");
strcat(line,emailfrom);
strcat(line,"\n");
strcat(line,"Subject:");
strcat(line,emailsubject);
strcat(line,"\n");
strcat(line,emailmessage);
strcat(line,"\r\n.\r\n");
fputs(line,smtpfile);
bytes_sent=send(sockfd,line,strlen(line),0);
sleep(waittime);
err=recv(sockfd,Rec_Buf,bufsize,0);Rec_Buf[err] = '\0';
fputs(Rec_Buf,smtpfile);
strcpy(line,"quit\n");
fputs(line,smtpfile);
bytes_sent=send(sockfd,line,strlen(line),0);
sleep(waittime);
err=recv(sockfd,Rec_Buf,bufsize,0);Rec_Buf[err] = '\0';
fputs(Rec_Buf,smtpfile);
fclose(smtpfile);
#ifdef WIN32
closesocket(sockfd);
WSACleanup();
#else
close(sockfd);
#endif
}

however, my mailserver(for which i pay for hosting) is tls only for
security, and requires authentication, so I am not sure how to modify
the code to authenticate over tls and send an email....

any help is appreciated.

Mar 7 '06 #1
11 2211
za****@gmail.com wrote:
hi, i have this code which is part of a main program, to email from
within the program a log file:
Your question as well as your code are off-topic in c.l.c. Try to find
a group that deals with mail protocols (I'd tell you which one/s/ but I
don't know).

Still, some remarks on what I see below:

1. Your code is hard to read. Better use of spacing would help a lot.
int MailIt (char *mailserver, char *emailto, char *emailfrom,
char *emailsubject, char *emailmessage) {
SOCKET sockfd;
WSADATA wsaData;
FILE *smtpfile;

#define bufsize 300
2. Macros are conventionally all-caps (unlike types and variables).
int bytes_sent; /* Sock FD */
int err;
struct hostent *host; /* info from gethostbyname */
struct sockaddr_in dest_addr; /* Host Address */
char line[1000];
char *Rec_Buf = (char*) malloc(bufsize+1);
3. Don't cast return value of malloc(). It may hide error of not
including stdlib.h.

There's probably more, but it's hard to read, so I quit.

<snip loads of off-topic code>
however, my mailserver(for which i pay for hosting) is tls only for
security, and requires authentication, so I am not sure how to modify
the code to authenticate over tls and send an email....


See the the top comment.

--
BR, Vladimir

Mar 7 '06 #2
za****@gmail.com wrote:
hi, i have this code which is part of a main program, to email from
within the program a log file:
<snip>
#ifdef WIN32
closesocket(sockfd);
WSACleanup();
#else
close(sockfd);
#endif
}

however, my mailserver(for which i pay for hosting) is tls only for
security, and requires authentication, so I am not sure how to modify
the code to authenticate over tls and send an email....


Sockets, tls, ssl and the like are not part of standard C so you will
have to ask on groups dedicated to your implementations or socket
programming (if there are any). From the looks of it you are supporting
both Windows and POSIX systems, so you might have to ask on a couple of
groups. I would suggest comp.unix.programmer and one of the microsoft
groups as starting points, although you should check their FAQs and read
a few days posts first. Had you done that here you might have realised
that your question was not topical.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Mar 7 '06 #3
"Vladimir S. Oka" <no****@btopenworld.com> writes:
za****@gmail.com wrote:

[...]
int MailIt (char *mailserver, char *emailto, char *emailfrom,
char *emailsubject, char *emailmessage) {
SOCKET sockfd;
WSADATA wsaData;
FILE *smtpfile;

#define bufsize 300


2. Macros are conventionally all-caps (unlike types and variables).


But FILE, defined in <stdio.h>, is an exception to this.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Mar 7 '06 #4
On Tue, 07 Mar 2006 20:49:03 GMT, Keith Thompson <ks***@mib.org> wrote
in comp.lang.c:
"Vladimir S. Oka" <no****@btopenworld.com> writes:
za****@gmail.com wrote:

[...]
int MailIt (char *mailserver, char *emailto, char *emailfrom,
char *emailsubject, char *emailmessage) {
SOCKET sockfd;
WSADATA wsaData;
FILE *smtpfile;

#define bufsize 300


2. Macros are conventionally all-caps (unlike types and variables).


But FILE, defined in <stdio.h>, is an exception to this.


Just curious, have you ever seen a <stdio.h> where FILE is not a macro
(i.e., a typedef?). I don't think I ever have.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Mar 8 '06 #5
Jack Klein <ja*******@spamcop.net> writes:
Just curious, have you ever seen a <stdio.h> where FILE is not a macro
(i.e., a typedef?). I don't think I ever have.


In the locally installed glibc it appears to just be a typedef:
typedef struct _IO_FILE FILE;
There's a lot of conditional inclusion nonsense nearby so I might
be missing a macro definition.

You appear to be equating macros and typedefs. I don't
understand that.
--
"What is appropriate for the master is not appropriate for the novice.
You must understand the Tao before transcending structure."
--The Tao of Programming
Mar 8 '06 #6
Jack Klein <ja*******@spamcop.net> writes:
On Tue, 07 Mar 2006 20:49:03 GMT, Keith Thompson <ks***@mib.org> wrote
in comp.lang.c:
"Vladimir S. Oka" <no****@btopenworld.com> writes:
> za****@gmail.com wrote:

[...]
>> int MailIt (char *mailserver, char *emailto, char *emailfrom,
>> char *emailsubject, char *emailmessage) {
>> SOCKET sockfd;
>> WSADATA wsaData;
>> FILE *smtpfile;
>>
>> #define bufsize 300
>
> 2. Macros are conventionally all-caps (unlike types and variables).


But FILE, defined in <stdio.h>, is an exception to this.


Just curious, have you ever seen a <stdio.h> where FILE is not a macro
(i.e., a typedef?). I don't think I ever have.


Typedefs are not macros.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Mar 8 '06 #7
In article <b0********************************@4ax.com>,
Jack Klein <ja*******@spamcop.net> wrote:
Just curious, have you ever seen a <stdio.h> where FILE is not a macro
(i.e., a typedef?). I don't think I ever have.


SGI IRIX 6.2 and SGI IRIX 6.5 have it as a typedef.
--
If you lie to the compiler, it will get its revenge. -- Henry Spencer
Mar 8 '06 #8
Keith Thompson <ks***@mib.org> writes:
Jack Klein <ja*******@spamcop.net> writes:
On Tue, 07 Mar 2006 20:49:03 GMT, Keith Thompson <ks***@mib.org> wrote
in comp.lang.c:
"Vladimir S. Oka" <no****@btopenworld.com> writes:
> za****@gmail.com wrote:
[...]
>> int MailIt (char *mailserver, char *emailto, char *emailfrom,
>> char *emailsubject, char *emailmessage) {
>> SOCKET sockfd;
>> WSADATA wsaData;
>> FILE *smtpfile;
>>
>> #define bufsize 300
>
> 2. Macros are conventionally all-caps (unlike types and variables).

But FILE, defined in <stdio.h>, is an exception to this.


Just curious, have you ever seen a <stdio.h> where FILE is not a macro
(i.e., a typedef?). I don't think I ever have.


Typedefs are not macros.


Or did you mean "a typedef" to correspond to "not a macro" rather than
to "a macro"? If so, the question at least makes sense, but FILE is
usually a typedef (not a macro) in all the <stdio.h> implementations
I've seen.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Mar 8 '06 #9
Keith Thompson <ks***@mib.org> writes:
[...]
Or did you mean "a typedef" to correspond to "not a macro" rather than
to "a macro"? If so, the question at least makes sense, but FILE is
usually a typedef (not a macro) in all the <stdio.h> implementations
I've seen.


That last sentence ("usually ... all") was a victim of careless
editing and insufficient proofreading.

I think that FILE is a typedef (not a macro) in all the <stdio.h>
implementations I've seen. I know it's a typedef in all the <stdio.h>
implementations I have easy access to at the moment (Linux, Cygwin,
Solaris, AIX, OSF); the fact that those are all Unix-like systems may
imply some bias.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Mar 8 '06 #10
On 2006-03-08, Keith Thompson <ks***@mib.org> wrote:
Keith Thompson <ks***@mib.org> writes:
[...]
Or did you mean "a typedef" to correspond to "not a macro" rather than
to "a macro"? If so, the question at least makes sense, but FILE is
usually a typedef (not a macro) in all the <stdio.h> implementations
I've seen.


That last sentence ("usually ... all") was a victim of careless
editing and insufficient proofreading.

I think that FILE is a typedef (not a macro) in all the <stdio.h>
implementations I've seen. I know it's a typedef in all the <stdio.h>
implementations I have easy access to at the moment (Linux, Cygwin,
Solaris, AIX, OSF); the fact that those are all Unix-like systems may
imply some bias.


Unix V7's stdio.h contains:

# ifndef FILE
extern struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
char _flag;
char _file;
} _iob[_NFILE];
# endif
#define FILE struct _iobuf

Like many things in modern C implementations, stdio was, of course,
invented for v7. [v6 had a bizarre precursor library, with no FILE's -
the user-visible API used file descriptors despite the fact that the
library maintained buffering etc.]
Mar 8 '06 #11
On 7 Mar 2006 06:48:53 -0800, "za****@gmail.com" <za****@gmail.com>
wrote:

#if mostly_offtopic but see some points below
hi, i have this code which is part of a main program, to email from
within the program a log file:

int MailIt (char *mailserver, char *emailto, char *emailfrom,
char *emailsubject, char *emailmessage) {
SOCKET sockfd;
WSADATA wsaData;
FILE *smtpfile;

#define bufsize 300
int bytes_sent; /* Sock FD */
int err;
struct hostent *host; /* info from gethostbyname */
struct sockaddr_in dest_addr; /* Host Address */
char line[1000];
char *Rec_Buf = (char*) malloc(bufsize+1);
It's odd to make 1000 bytes automatic but 300+1 dynamic (heap). Legal,
but odd. Unless there's a reason for the difference, be consistent.
smtpfile=fopen(SMTPLog,"a+");
Your code doesn't need + (update), and you should check the result of
fopen for a null pointer (indicating failure) before using it.
if (WSAStartup(0x202,&wsaData) == SOCKET_ERROR) {
fputs("WSAStartup failed",smtpfile);
WSACleanup();
return -1;
}
As you conditionalize Windows/Unix below, this should be Win-only.
if ( (host=gethostbyname(mailserver)) == NULL) {
perror("gethostbyname");
exit(1);
}
memset(&dest_addr,0,sizeof(dest_addr));
memcpy(&(dest_addr.sin_addr),host->h_addr,host->h_length);

/* Prepare dest_addr */
dest_addr.sin_family= host->h_addrtype; /* AF_INET from
gethostbyname */
dest_addr.sin_port= htons(25); /* PORT defined above */

/* Get socket */

if ((sockfd=socket(AF_INET,SOCK_STREAM,0)) < 0) {
perror("socket");
exit(1);
}
This shouldn't work for Windows where SOCKET is a handle -- and the
part above would work _only_ for Windows. Should test ==
INVALID_SOCKET, which you can easily make work on Unix also.
/* Connect !*/
fputs("Connecting....\n",smtpfile);

if (connect(sockfd, (struct sockaddr
*)&dest_addr,sizeof(dest_addr)) == -1){
perror("connect");
exit(1);
}
Your other checks are for SOCKET_ERROR; this is inconsistent.
sleep(waittime);
err=recv(sockfd,Rec_Buf,bufsize,0);Rec_Buf[err] = '\0';
fputs(Rec_Buf,smtpfile);
There's no point in sleep'ing before recv'ing on a blocking socket.
The return from recv, as other POSIX I/O calls, can be negative, in
which case the array indexing is invalid. To be really picky, you
shouldn't assume a "message" from the other end of a TCP connection,
here the server banner, will always be received by one recv() call.
However, you have more serious problems to deal with.
strcpy(line,"helo me.somepalace.com\n");
fputs(line,smtpfile);
bytes_sent=send(sockfd,line,strlen(line),0);
SMTP commands (and responses), like most(?) other textual Internet
protocols, must end with CR LF. \n is a single character, almost
certainly (not absolutely) LF, but can't be two. For I/O to a text
stream using <stdio.h>, \n will be translated to (and from) the
system's line delimiter which on _some_ systems like Windows is CR LF,
but even there no such thing happens for socket routines.
sleep(waittime);
err=recv(sockfd,Rec_Buf,bufsize,0);Rec_Buf[err] = '\0';
fputs(Rec_Buf,smtpfile);
strcpy(line,"MAIL FROM:<");
strncat(line,emailfrom,strlen(emailfrom));
This will always terminate at the count rather than the null, and thus
not correctly terminate the string you're building. At best, if the
value you build here is shorter than the value you did above, you just
get a mixed wrong value; at worst, if your next line runs off into
uninitialized memory you officially get Undefined Behavior which could
in theory be anything up to nasal demons, and in practice will often
be a crash or garbage data.
strncat(line,">\n",3);
This works if the above line didn't leave an invalid string, but both
the previous one and this one could more easily use strcat() no n.
Or you could replace all three lines by
sprintf (line, "MAIL FROM <%s>\r\n", emailfrom);
(Note added CR per above. Or even better \x0D\x0A, although for a
seriously non-ASCII machine you need many other changes as well.)

But either of these ways is vulnerable to overflow if the supplied
string is too long; at simplest you could use
sprintf (line, "MAIL FROM <%.120s>\r\n", emailfrom);
which is small enough it won't cause problems on any real destination
but large enough to be useful. If you know more about the destinations
you will be talking to, and need to, could increase accordingly.

Aside: for limiting sprintf in general in a C99 implementation (rare)
or as an extension to C89 (more common) you can use snprintf. However,
it truncates without regard to the data content, which in this case
gives you a malformed command.
fputs(line,smtpfile);
bytes_sent=send(sockfd,line,strlen(line),0);
sleep(waittime);
err=recv(sockfd,Rec_Buf,bufsize,0);Rec_Buf[err] = '\0';
fputs(Rec_Buf,smtpfile);
You should always check the SMTP response before continuing. In theory
you should even have checked the banner.
strcpy(line,"RCPT TO:<");
strncat(line,emailto,strlen(emailto));
strncat(line,">\n",3);
fputs(line,smtpfile);
bytes_sent=send(sockfd,line,strlen(line),0);
sleep(waittime);
err=recv(sockfd,Rec_Buf,bufsize,0);Rec_Buf[err] = '\0';
fputs(Rec_Buf,smtpfile);
Ditto and ditto, and more below.
strcpy(line,"DATA\n");
fputs(line,smtpfile);
bytes_sent=send(sockfd,line,strlen(line),0);
sleep(waittime);
err=recv(sockfd,Rec_Buf,bufsize,0);Rec_Buf[err] = '\0';
fputs(Rec_Buf,smtpfile);
sleep(waittime);
strcpy(line,"To:");
strcat(line,emailto);
strcat(line,"\n");
strcat(line,"From:");
strcat(line,emailfrom);
strcat(line,"\n");
strcat(line,"Subject:");
strcat(line,emailsubject);
strcat(line,"\n");
strcat(line,emailmessage);
strcat(line,"\r\n.\r\n");
You finally got (part of) one right -- probably because without it
some servers weren't Postelian enough to recognize the (vital) EOM.
fputs(line,smtpfile);
bytes_sent=send(sockfd,line,strlen(line),0);
sleep(waittime);
err=recv(sockfd,Rec_Buf,bufsize,0);Rec_Buf[err] = '\0';
fputs(Rec_Buf,smtpfile);
strcpy(line,"quit\n");
fputs(line,smtpfile);
bytes_sent=send(sockfd,line,strlen(line),0);
sleep(waittime);
err=recv(sockfd,Rec_Buf,bufsize,0);Rec_Buf[err] = '\0';
fputs(Rec_Buf,smtpfile);
fclose(smtpfile);
#ifdef WIN32
closesocket(sockfd);
WSACleanup();
#else
close(sockfd);
#endif
You don't free(Rec_Buf); this is a memory leak.
}

however, my mailserver(for which i pay for hosting) is tls only for
security, and requires authentication, so I am not sure how to modify
the code to authenticate over tls and send an email....

Almost certainly your best bet is to use openssl, an opensource
library, if BSD-style terms are acceptable. See www.openssl.org.

Even so, it's not trivial; SSL/TLS is a pretty big protocol,
especially with all the options. At the level of understanding this
code displays, if your systems allow it, which both Windows and (any)
Unix do, you might be better off using system() to invoke a separate
(prebuilt) mail-sending program.

- David.Thompson1 at worldnet.att.net
Mar 20 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
13692
by: RandRace | last post by:
I'm having some problems with a little script i wrote using net::smtp. I originally wrote it in linux where it works perfectly. I tried to use it from windows the other day and it doesn't work. It...
4
1712
by: kim jørgensen | last post by:
Hi i am trying to write a email clint for my labtop. my problem is that am not always on the same network and can not always reach the same Smtp server- so i am looking for a funcktion which can...
1
8026
by: bivin | last post by:
hai i am requesting your technical support. please help me. i have been working with this for five days. the problem is relating with the smtp. i am trying to send an email from the asp.net...
34
18139
by: antonyliu2002 | last post by:
I've set up the virtual smtp server on my IIS 5.1 like so: 1. Assign IP address to "All Unassigned", and listen to port 25. 2. Access Connection granted to "127.0.0.1". 3. Relay only allow...
4
7668
by: =?Utf-8?B?dHBhcmtzNjk=?= | last post by:
I have a web page that at the click of a button must send a bunch (1000+) emails. Each email is sent individually. I have the code working fine, using Mail Message classes and smtp and all that. ...
7
7718
by: oopsbabies | last post by:
Hello everyone, I am using Apache 1.3.33 as the web server and PHP version 4.3.10. My machine is using Windows XP 2002 professional edition which comes with a Windows firewall. I am using McAfee...
9
1711
by: sweatha | last post by:
Hi I have the normal server and not the SMTP service installed. I need to send a mail once if I click a button. Can anybody help me regarding that
0
7194
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7267
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
6976
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
5566
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
4993
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4666
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3160
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3148
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
372
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.