/* this is libspopc.h file. * this is part of the libspopc library sources * copyright © 2002 Benoit Rouits <brouits@free.fr> * released under the terms of GNU LGPL * (GNU Lesser General Public Licence). * libspopc offers simple API for a pop3 client (MDA). * See RFC 1725 for pop3 specifications. * more information on http://brouits.free.fr/libspopc/ */ #ifndef LIBSPOPC_H #define LIBSPOPC_H #ifdef __cplusplus extern "C" { #endif #include <sys/types.h> #ifdef WIN32 #include <winsock.h> #else #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #endif #ifdef USE_SSL #include <openssl/ssl.h> /****************************************************************************** * If compiled with SSL support, the low-level functions will act on a * "pop3sock" structure, which contains the socket, SSL instance and context * for the connection. This structure is dynamically allocated and initialized * when you do pop3_prepare() or popbegin(), and is cleaned-up and destroyed in * pop3_disconnect() or popend(). ******************************************************************************/ typedef struct { int sock; SSL *ssl; SSL_CTX *ctx; } pop3sock; typedef pop3sock* pop3sock_t; #define BAD_SOCK NULL /****************************************************************************** * Use pop3_cert_setup() to specify the location of your SSL certificate * bundle. If it is not set (or set to NULL), SSL connections can be still be * made, but certificates will not be verified! * This function sets a global variable, and should be called before * pop3_prepare() or popbegin() if you want to verify certs. * * Hint: If you have a recent version of curl/libcurl installed, you can try * setting this to the output of: "curl-config --ca" ******************************************************************************/ void pop3_cert_setup(char *certfile); #else /* Non-SSL */ /****************************************************************************** * If the library is compiled without SSL, the "pop3sock_t" type is a simple * integer (i.e. socket) and all the functions should work just as they did * in previous libspopc versions. ******************************************************************************/ typedef int pop3sock_t; #define BAD_SOCK -1 #endif /* SSL */ /*************************************** * low-level methods for a pop3 client * ***************************************/ #define SOCKET_TIMEOUT 15 #define TCPBUFLEN 512 /****************************************************************************** * Be careful, using the low-level API is uncompliant with using the high * level API. Here, you make your choice. If you don't know the pop3 protocol * or what a socket is, it is then warmly recommended to use the *high-level* * API if which is shown far below on this file. ******************************************************************************/ /************** * connecting * **************/ pop3sock_t pop3_prepare(const char* servername, const int port, struct sockaddr_in* connection, struct hostent* server); /* prepares the pop session and returns a socket descriptor, or BAD_SOCK on error */ char* pop3_connect(pop3sock_t sock, struct sockaddr_in* connection); /* connects to the server through the sock and returns server's welcome */ void pop3_disconnect(pop3sock_t sock); /* close socket */ /**************** * pop3 queries * ****************/ char* pop3_user(pop3sock_t sock, const char* name); /* performs "USER" pop query and returns server's <512 bytes response */ char* pop3_pass(pop3sock_t sock, const char* pw); /* performs "PASS" pop query and return server's <512 bytes response */ char* pop3_quit(pop3sock_t sock); /* performs "QUIT" pop query and returns server's <512 bytes response */ char* pop3_stat(pop3sock_t sock); /* performs "STAT" pop query and returns server's <512 bytes response */ char* pop3_list(pop3sock_t sock, int id); /* performs a "LIST" pop query and returns server's (long) response */ char* pop3_retr(pop3sock_t sock, int id); /* performs a "RETR" pop query and returns server's (long) response */ char* pop3_dele(pop3sock_t sock, int id); /* performs a "DELE" pop query and returns server's <512 bytes response */ char* pop3_noop(pop3sock_t sock); /* performs a "NOOP" pop query and returns server's <512 bytes response */ char* pop3_rset(pop3sock_t sock); /* performs a "RSET" pop query and returns server's <512 bytes response */ char* pop3_top(pop3sock_t sock, int id, int lines); /* performs a "TOP" pop query and returns server's (long) response */ char* pop3_uidl(pop3sock_t sock, int id); /* performs a "UIDL" pop query and returns server's (long) response */ char* pop3_apop(pop3sock_t sock, const char* name, const char* digest); /* performs a "APOP" secure pop query and returns server's <512 bytes response */ /********************* * parsing utilities * *********************/ #define DOTBEGIN(s) ((s)[0]=='\n'&&(s)[1]=='.') int dotline(char* buf); /* returns 1 if buf contains a "\n.\n" or "\n.\0" or \r.(etc) substring */ /* buf must be terminated by '\0' */ int pop3_error(char* string); /* returns 1 if pop server error reply (i.e : -ERR ...) */ /************************************ * reply re-formatting, after query * ************************************/ char* nextline(char* string); /* returns a pointer to the next line of given string */ char* retr2msg(char* data); /* returns formatted mail from a pop RETR X query */ /* must only be called on data returned by pop3_retr() */ void freemsg(char* msg); /* free the message received by reetr2msg */ int* list2array(char* poplist); /* WARNING: must not be called after a mail deletion */ /* returns an int array of sizes of messages from a LIST pop query */ /* array[0] holds id of the array's last element */ /* must only be called on data received by a pop3_list(sock,0) request */ void freelistarray(int* array); /* free the message sizes array created by list2array */ int listi2size(char* resp); /* grep the given size (in bytes) in resp after a pop3_list(sock,ID) request */ /* do not use after a pop3_list(sock,0) ! */ int stat2last(char* resp); /* returns the last message's id on pop server */ int stat2bytes(char* resp); /* returns the sumsize in bytes of all stored messages on server */ /* must only be called just after a pop3_stat() request */ char** uidl2array(char* resp); /* WARNING: mus not be called after a mail deletion */ /* returns an array of unique strings for each message id */ /* array[0] gives array's last id */ /* must only be called just after a pop3_uidl(sock,0) request */ void freeuidlarray(char** arrray); /* free the uidl array created by uidl2array */ char* uidli2sig(char* resp); /* grep the pop signature of *one* message signature reply*/ /* should only be called on data received by a pop3_uidl(sock,ID) request */ /* do not use it after a pop3_uidl(sock,0) ! */ /*************************************************** * high-level API for a SIMPLE MDA/MUA * ***************************************************/ /****************************************************************************** * This is the high-level API of libspopc and it is recommended to use it * instead of the low-level one. This high-level API, in spite of its very * 'teasing' name, just provides a *very simple* way to access and query a * pop3 server with your e-mail client. This API handles pop3 in a very * convenient manner for the non 'socket-aware' C developper. ******************************************************************************/ typedef enum{AUTHORIZATION,TRANSACTION,UPDATE}popstate; /* pop server states definition from RFC 1725, not used here actually */ typedef struct{ pop3sock_t sock;/* socket descriptor */ struct sockaddr_in* connection; struct hostent* server; popstate state;/* pop server state */ int* list;/* pop messages size list */ char** uidl;/* pop messages signature list */ int bytes;/* total stored (in bytes) on pop server */ int last;/* last message id */ int del;/* 0|1 flag to ask deletion of retrieved messages */ }popsession; #define popbytes(s) ((s)->bytes) /* gives the total stored data size (in bytes) on the pop server */ /* arg 's' is type 'popsession*'; 'result' is type 'int' */ #define popsetdel(s) ((s)->del=1) /* asks the session to delete any retrieved messages on the server */ /* arg 's' is type 'popsession*' */ #define popsetundel(s) ((s)->del=0) /* asks the session to not delete any retrieved message on the server */ /* arg 's' is type 'popsession*' */ #define popmsgsize(s,i) ((s)->list[(i)]) /* gives the size of message 'i' for session 's' */ /* args are type 'session*'(s) and 'int'(i) */ /* 'i' must *not* be 0 */ #define popmsguid(s,i) ((s)->uidl[(i)]) /* points to the 'char*' uid (unique signature) of 'int'(i) message id */ int poplast(popsession* session); /* gives the id of the last message of the current session */ int popnum(popsession* session); /* gives the current number of stored message. it is != to poplast() */ char* popbegin(const char* servername,const char* user, const char* pass, popsession** sp); /* prepares, connect and get lists of messages stored on pop server */ /* you must give a valid servername, user and pass */ /* returns an error message if a problem occurs, else NULL */ char* popgethead(popsession* session, int id); /* returns the header of a message (id between 1 and poplast()) or NULL if bad id */ char* popgetmsg(popsession* session, int id); /* returns a message (id between 1 and poplast()) or NULL if bad id */ int popdelmsg(popsession* session, int id); /* deletes message 'id' on pop server */ /* returns -1 if server error, 0 else */ int popcancel(popsession* session); /* cancels all previous deletion on pop server */ /* returns -1 if server error, 0 else */ void popend(popsession* session); /* quit and destroys pop session */ #ifdef __cplusplus } #endif #endif