email program.........

Discussion in 'C Programming' started by /*24age*/, Jul 13, 2006.

  1. /*24age*/

    /*24age*/ Guest

    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(
    "", /* from */
    "", /* 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;
    }
     
    /*24age*/, Jul 13, 2006
    #1
    1. Advertising

  2. /*24age*/

    Tom St Denis Guest

    /*24age*/ wrote:
    > 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
     
    Tom St Denis, Jul 13, 2006
    #2
    1. Advertising

  3. /*24age*/

    Jack Klein Guest

    On 13 Jul 2006 15:16:54 -0700, "/*24age*/" <> wrote in
    comp.lang.c:

    > 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.

    --
    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/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Jul 14, 2006
    #3
  4. On 13 Jul 2006 15:16:54 -0700, "/*24age*/" <> wrote:

    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(
    > "", /* from */
    > "", /* 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
     
    Dave Thompson, Jul 24, 2006
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Peter
    Replies:
    0
    Views:
    3,426
    Peter
    Jul 1, 2003
  2. John Silver
    Replies:
    0
    Views:
    634
    John Silver
    Feb 4, 2005
  3. Tee

    Email ErrorPage to email

    Tee, Jun 23, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    397
  4. Replies:
    3
    Views:
    569
    AdamM
    Jul 27, 2004
  5. Chuck Amadi
    Replies:
    2
    Views:
    420
    chuck amadi
    Jun 6, 2004
Loading...

Share This Page