POP3 server - basic client operations in raw C++

986 Views Asked by At

I've spent at least 2 last hours searching for a way to make a simple connection to a POP3 server and get the number of messages waiting on it. As it's childlish-easy in C# and seems pretty basic in C++ on linux, I just can't find even the slightest tutorial on how to make it work on Windows.

I don't want to use any third-party libraries - i just want to code a simple console program, using raw C++ only, just to do some basic stuff as described above. All the sources I've tried to study are like:

POP3 is a protocol that has somethng to do with emails and it's very simple. Now let's proceed to writing a multi-platform POP3 server-client application, using a F16 fighter jet and inventing a time machine in progress.

I just can't seem to find any SIMPLE solutions...

I've written (with some help) a simple snippet that SHOULD work on linux - at least according to the tutorials; I have no means to check it right now. Hovewer, the C++ is not my "native language" and when I try to transfer it into Windows, I just fall from one hole into the other and have to spend yet another quarter of an hour GGoogle'ing the solution.

At this point, the code is compiling, but the linker fails. It's strange, because I've added the ws2_32.lib to the linker, so it SHOULD work just fine. In return, I only get loads of LNK2019.

Can you please help me with the code or provide any link to a SIMPLE solution that works on Windows?

The code:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN 1
    #include <winsock2.h>
    #include <windows.h>
#else

#endif
#ifndef in_addr_t
    #define in_addr_t long
#endif
#include <string.h>

void err(char *where) {
    fprintf(stderr, "error in %s: %d\n", where, errno);
    exit(1);
}

int main(int argc, char *argv[]) {
    char *remote = "some_address";
    struct servent *sent;
    struct protoent *pent;
    int port;
    int sock;
    int result;
    in_addr_t ipadr;
    struct sockaddr_in addr;
    struct hostent *hent;
    char buf[2048];
    sent = getservbyname("http", "pop3");
    if(sent == NULL)
    err("getservbyname");
    port = sent->s_port;
    pent = getprotobyname("pop3");
    if(pent == NULL)
    err("getprotobyname");
    hent = gethostbyname(remote);
    printf("Host: %s\n", hent->h_name);
    printf("IP: %s\n", inet_ntoa(*((struct in_addr *)hent->h_addr)));
    addr.sin_family = AF_INET;
    addr.sin_port = port;
    addr.sin_addr = *((struct in_addr *)hent->h_addr);
    memset(addr.sin_zero, '\0', 8);
    sock = socket(AF_INET, SOCK_STREAM, pent->p_proto);
    if(sock < 0)
    err("socket");
    result = connect(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr));
    if(result < 0)
    err("connect");
}
1

There are 1 best solutions below

0
On BEST ANSWER

You have to add WSAStartup before you use any Winsock function. When you are done, you have to call WSACleanup.

Example(from msdn):

WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD(2, 2);

err = WSAStartup(wVersionRequested, &wsaData);

if (err != 0)
{
    return 1;
}

//Do stuf here

WSACleanup();