It's been around for more then 10 years and it implements virtually anything you would want to do with SMTP, IMAP or POP, albeit in ANSI C which makes things a bit more challenging, especially when you go through the sources and try to follow the pointer arithmetic being used.
I haven't touched c-client since 2001 (that's 8 years ago) and I've run into a pleasant surprise finding c-client alive and well in 2009, and compiling "out of the box" on Snow Leopard on 64 bit. Many thanks, Mark Crispin.
Here's how you write a small application that acts as a SMTP client.
1/ Download the distribution (ftp://ftp.cac.washington.edu/imap/imap.tar.Z)
2/ Un-archive the distribution
3/ Build the distribution
cd imap-2007e/
make osx
4/ Build a small application that sends an SMTP message
c-client requires an application linking against it to implement a set of functions.
These are grouped in our example under the file called c-client-interface.c:
// --------------------- c-client-interface.c --------------------------------
#include <stdio.h>
void mm_searched (MAILSTREAM *stream,unsigned long number) {}
void mm_exists (MAILSTREAM *stream,unsigned long number) {}
void mm_expunged (MAILSTREAM *stream,unsigned long number){}
void mm_flags (MAILSTREAM *stream,unsigned long number) {}
void mm_notify (MAILSTREAM *stream,char *string,long errflg) {}
void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes) {}
void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes) {}
void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status) {}
void mm_log (char *string,long errflg)
{
fprintf(stdout, "mm_log: %s\n", string);
}
void mm_dlog (char *string)
{
fprintf(stdout, "mm_dlog: %s\n", string);
}
void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
{
fprintf(stdout, "mm_login for mb->user: %s\n", mb->user);
strcpy(user, mb->user);
strcpy(pwd, "passwordGoesHere");
}
void mm_critical (MAILSTREAM *stream) {}
void mm_nocritical (MAILSTREAM *stream) {}
long mm_diskerror (MAILSTREAM *stream,long errcode,long serious) {}
void mm_fatal (char *string) {}
We implement only three functions from the interface, namely mm_log and mm_dlog for logging purposes and mm_login, required to provide the password for our SMTP authentication when the server requires it.
The application itself is as basic as it gets. Note the host specification (it contains "novalidate-cert" because the certificate on our mail server is invalid).
The host specification is used by the smtp_open call that takes care of all the hard work that goes behind the scenes, that is the negotiation in between c-client and the SMTP server.
// --------------------- test.c ------------------------------------
#include <c-client.h>
#include "c-client-interface.c"
int main()
{
#include "linkage.c"
char * hostlist[] = { "mail.somedomain.com/ssl/novalidate-cert/user=senderUserName", NULL };
SENDSTREAM * sndstream = smtp_open(hostlist, 0);
if(sndstream == NULL)
{
fprintf(stderr, "Can't open SMTP connection\n");
return 1;
}
BODY * body = mail_newbody();
ENVELOPE * env = mail_newenvelope();
ADDRESS * to = mail_newaddr();
// data about the sender
env->from = mail_newaddr();
env->from->personal = strdup("Sender Full Name");
env->from->mailbox = strdup("senderUserName");
env->from->host = strdup("somedomain.com");
// subject for our message
env->subject = strdup("subject");
// destination for our message (the recipient)
rfc822_parse_adrlist(&env->to, strdup("recipientUserName"), strdup("destinationdomain.com"));
// the content of our message
body->type = TYPETEXT;
char *text = (char *) fs_get (8*MAILTMPLEN);
strcpy(text, "test message \015\012\0");
body->contents.text.data = text;
body->contents.text.size = strlen(text);
long result = smtp_mail(sndstream, "MAIL", env, body);
if(sndstream)
smtp_close(sndstream);
mail_free_envelope(&env);
mail_free_body(&body);
}
To build the application, once you saved the c-client-interface.c and the test.c files, you need to run (assuming you've unarchived the imap archive on your Desktop):
gcc test.c -L ~/Desktop/imap-2007e/c-client/c-client.a -I ~/Desktop/imap-2007e/c-client -lcrypto -lssl -lkrb4
Oh, and if you compile on Snow Leopard you will get a 64 bit application:
cristi:c-client diciu$ file ./a.out
./a.out: Mach-O 64-bit executable x86_64

0 comments:
Post a Comment