Browse Source

added IMAP example

dvh-chacham15-master
DINH Viet Hoa 10 years ago
parent
commit
643dcd2a6b
5 changed files with 260 additions and 40 deletions
  1. +1
    -1
      tests/Makefile.am
  2. +21
    -0
      tests/README
  3. +210
    -0
      tests/imap-sample.c
  4. +8
    -5
      tests/mime-create.c
  5. +20
    -34
      tests/mime-parse.c

+ 1
- 1
tests/Makefile.am View File

@ -33,7 +33,7 @@ EXTRA_DIST = README
noinst_PROGRAMS = smime decrypt pgp frm frm-tree frm-simple \
readmsg-simple fetch-attachment smtpsend readmsg-uid \
readmsg compose-msg
readmsg compose-msg imap-sample mime-create mime-parse
# For W32, reverse the -DLIBETPAN_DLL. Unfortunately, CFLAGS comes
# after AM_CPPFLAGS, so we have to frob CFLAGS.


+ 21
- 0
tests/README View File

@ -1,3 +1,24 @@
imap-sample
-----------
connect to Gmail IMAP server and fetches the messages of INBOX to a folder "download"
syntax: imap-sample mygmailaccount@gmail.com mypassword
mime-parse
----------
parse a MIME message and show the structure
syntax: mime-parse emailfile.eml
mime-create
-----------
create a message and show the resulting RFC 2822 format
syntax: mime-create
compose-msg
-----------


+ 210
- 0
tests/imap-sample.c View File

@ -0,0 +1,210 @@
#include <libetpan/libetpan.h>
#include <stdlib.h>
#include <sys/stat.h>
static void check_error(int r, char * msg)
{
if (r == MAILIMAP_NO_ERROR)
return;
if (r == MAILIMAP_NO_ERROR_AUTHENTICATED)
return;
if (r == MAILIMAP_NO_ERROR_NON_AUTHENTICATED)
return;
fprintf(stderr, "%s\n", msg);
exit(EXIT_FAILURE);
}
static char * get_msg_att_msg_content(struct mailimap_msg_att * msg_att, size_t * p_msg_size)
{
clistiter * cur;
/* iterate on each result of one given message */
for(cur = clist_begin(msg_att->att_list) ; cur != NULL ; cur = clist_next(cur)) {
struct mailimap_msg_att_item * item;
item = clist_content(cur);
if (item->att_type != MAILIMAP_MSG_ATT_ITEM_STATIC) {
continue;
}
if (item->att_data.att_static->att_type != MAILIMAP_MSG_ATT_BODY_SECTION) {
continue;
}
* p_msg_size = item->att_data.att_static->att_data.att_body_section->sec_length;
return item->att_data.att_static->att_data.att_body_section->sec_body_part;
}
return NULL;
}
static char * get_msg_content(clist * fetch_result, size_t * p_msg_size)
{
clistiter * cur;
/* for each message (there will be probably only on message) */
for(cur = clist_begin(fetch_result) ; cur != NULL ; cur = clist_next(cur)) {
struct mailimap_msg_att * msg_att;
size_t msg_size;
char * msg_content;
msg_att = clist_content(cur);
msg_content = get_msg_att_msg_content(msg_att, &msg_size);
if (msg_content == NULL) {
continue;
}
* p_msg_size = msg_size;
return msg_content;
}
return NULL;
}
static void fetch_msg(struct mailimap * imap, uint32_t uid)
{
struct mailimap_set * set;
struct mailimap_section * section;
char filename[20];
size_t msg_len;
char * msg_content;
FILE * f;
struct mailimap_fetch_type * fetch_type;
struct mailimap_fetch_att * fetch_att;
int r;
clist * fetch_result;
struct stat stat_info;
snprintf(filename, sizeof(filename), "download/%u.eml", (unsigned int) uid);
r = stat(filename, &stat_info);
if (r == 0) {
// already cached
printf("%u is already fetched\n", (unsigned int) uid);
return;
}
set = mailimap_set_new_single(uid);
fetch_type = mailimap_fetch_type_new_fetch_att_list_empty();
section = mailimap_section_new(NULL);
fetch_att = mailimap_fetch_att_new_body_peek_section(section);
mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
r = mailimap_uid_fetch(imap, set, fetch_type, &fetch_result);
check_error(r, "could not fetch");
printf("fetch %u\n", (unsigned int) uid);
msg_content = get_msg_content(fetch_result, &msg_len);
if (msg_content == NULL) {
fprintf(stderr, "no content\n");
mailimap_fetch_list_free(fetch_result);
return;
}
f = fopen(filename, "w");
if (f == NULL) {
fprintf(stderr, "could not write\n");
mailimap_fetch_list_free(fetch_result);
return;
}
fwrite(msg_content, 1, msg_len, f);
fclose(f);
printf("%u has been fetched\n", (unsigned int) uid);
mailimap_fetch_list_free(fetch_result);
}
static uint32_t get_uid(struct mailimap_msg_att * msg_att)
{
clistiter * cur;
/* iterate on each result of one given message */
for(cur = clist_begin(msg_att->att_list) ; cur != NULL ; cur = clist_next(cur)) {
struct mailimap_msg_att_item * item;
item = clist_content(cur);
if (item->att_type != MAILIMAP_MSG_ATT_ITEM_STATIC) {
continue;
}
if (item->att_data.att_static->att_type != MAILIMAP_MSG_ATT_UID) {
continue;
}
return item->att_data.att_static->att_data.att_uid;
}
return 0;
}
static void fetch_messages(struct mailimap * imap)
{
struct mailimap_set * set;
struct mailimap_fetch_type * fetch_type;
struct mailimap_fetch_att * fetch_att;
clist * fetch_result;
clistiter * cur;
int r;
/* as improvement UIDVALIDITY should be read and the message cache should be cleaned
if the UIDVALIDITY is not the same */
set = mailimap_set_new_interval(1, 0); /* fetch in interval 1:* */
fetch_type = mailimap_fetch_type_new_fetch_att_list_empty();
fetch_att = mailimap_fetch_att_new_uid();
mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
r = mailimap_fetch(imap, set, fetch_type, &fetch_result);
check_error(r, "could not fetch");
/* for each message */
for(cur = clist_begin(fetch_result) ; cur != NULL ; cur = clist_next(cur)) {
struct mailimap_msg_att * msg_att;
uint32_t uid;
msg_att = clist_content(cur);
uid = get_uid(msg_att);
if (uid == 0)
continue;
fetch_msg(imap, uid);
}
mailimap_fetch_list_free(fetch_result);
}
int main(int argc, char ** argv)
{
struct mailimap * imap;
int r;
/*
./imap-sample mygmailaccount@gmail.com mygmailpassword
*/
if (argc < 3) {
fprintf(stderr, "usage: imap-sample [gmail-email-address] [password]\n");
exit(EXIT_FAILURE);
}
mkdir("download", 0700);
imap = mailimap_new(0, NULL);
r = mailimap_ssl_connect(imap, "imap.gmail.com", 993);
fprintf(stderr, "connect: %i\n", r);
check_error(r, "could not connect to server");
r = mailimap_login(imap, argv[1], argv[2]);
check_error(r, "could not login");
r = mailimap_select(imap, "INBOX");
check_error(r, "could not select INBOX");
fetch_messages(imap);
mailimap_logout(imap);
mailimap_free(imap);
exit(EXIT_SUCCESS);
}

+ 8
- 5
tests/mime-create.c View File

@ -1,13 +1,14 @@
#include <libetpan/libetpan.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
static char * generate_boundary(const char * boundary_prefix);
static struct mailmime * get_text_part(const char * mime_type,
const char * text, size_t length, int encoding_type);
struct mailimf_fields * build_fields(void)
static struct mailimf_fields * build_fields(void)
{
struct mailimf_fields * fields;
struct mailimf_field * f;
@ -28,7 +29,7 @@ struct mailimf_fields * build_fields(void)
list = clist_new();
mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
strdup("dinh.viet.hoa@free.fr"));
strdup("dinh.viet.hoa@foobaremail.com"));
clist_append(list, mb);
mb_list = mailimf_mailbox_list_new(list);
@ -45,7 +46,7 @@ struct mailimf_fields * build_fields(void)
list = clist_new();
mb = mailimf_mailbox_new(strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?="),
strdup("dinh.viet.hoa@free.fr"));
strdup("dinh.viet.hoa@foobaremail.com"));
addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
clist_append(list, addr);
addr_list = mailimf_address_list_new(list);
@ -182,7 +183,6 @@ static struct mailmime * get_text_part(const char * mime_type,
struct mailmime_parameter * param;
struct mailmime_disposition * disposition;
struct mailmime_mechanism * encoding;
char * dup_content_id;
encoding = mailmime_mechanism_new(encoding_type, NULL);
disposition = mailmime_disposition_new_with_data(MAILMIME_DISPOSITION_TYPE_INLINE,
@ -219,7 +219,6 @@ static struct mailmime * get_file_part(const char * filename, const char * mime_
struct mailmime_content * content;
struct mailmime * mime;
struct mailmime_fields * mime_fields;
char * dup_content_id;
disposition_name = NULL;
if (filename != NULL) {
@ -247,6 +246,8 @@ static struct mailmime * get_sample_file_part(void)
part = get_file_part("file-data.jpg", "image/jpeg",
FILEDATA, sizeof(FILEDATA) - 1);
return part;
}
#define MAX_MESSAGE_ID 512
@ -332,5 +333,7 @@ int main(int argc, char ** argv)
col = 0;
mailmime_write_file(stdout, &col, mime);
mailmime_free(mime);
exit(0);
}

+ 20
- 34
tests/mime-parse.c View File

@ -1,34 +1,12 @@
#include <libetpan/libetpan.h>
#include <sys/stat.h>
#include <stdlib.h>
//#include <fcntl.h>
#include <stdio.h>
static void display_mime_content(struct mailmime_content * content_type);
static void display_mime_data(struct mailmime_data * data)
{
switch (data->dt_encoding) {
case MAILMIME_MECHANISM_7BIT:
printf("7bit\n");
break;
case MAILMIME_MECHANISM_8BIT:
printf("8bit\n");
break;
case MAILMIME_MECHANISM_BINARY:
printf("binary\n");
break;
case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
printf("quoted-printable\n");
break;
case MAILMIME_MECHANISM_BASE64:
printf("base64\n");
break;
case MAILMIME_MECHANISM_TOKEN:
printf("other\n");
break;
}
switch (data->dt_type) {
case MAILMIME_DATA_TEXT:
printf("data : %u bytes\n", (unsigned int) data->dt_data.dt_text.dt_length);
@ -144,8 +122,6 @@ static void display_group(struct mailimf_group * group)
static void display_address(struct mailimf_address * a)
{
clistiter * cur;
switch (a->ad_type) {
case MAILIMF_ADDRESS_GROUP:
display_group(a->ad_data.ad_group);
@ -293,8 +269,6 @@ void display_mime_type(struct mailmime_type * type)
static void display_mime_content(struct mailmime_content * content_type)
{
clistiter * cur;
printf("type: ");
display_mime_type(content_type->ct_type);
printf("/%s\n", content_type->ct_subtype);
@ -357,18 +331,28 @@ int main(int argc, char ** argv)
{
FILE * f;
int r;
int status;
struct mailmime * mime;
struct stat stat_info;
char * data;
size_t current_index;
char * filename;
status = EXIT_FAILURE;
if (argc < 2) {
fprintf(stderr, "syntax: mime-parse [filename]\n");
}
filename = argv[1];
f = fopen(filename, "r");
if (f == NULL) {
exit(EXIT_FAILURE);
}
r = stat(filename, &stat_info);
if (r != 0) {
fclose(f);
exit(EXIT_FAILURE);
}
data = malloc(stat_info.st_size);
fread(data, 1, stat_info.st_size, f);
fclose(f);
@ -376,13 +360,15 @@ int main(int argc, char ** argv)
current_index = 0;
r = mailmime_parse(data, stat_info.st_size,
&current_index, &mime);
if (r == MAILIMF_NO_ERROR) {
display_mime(mime);
/* do the things */
status = EXIT_SUCCESS;
mailmime_free(mime);
if (r != MAILIMF_NO_ERROR) {
free(data);
exit(EXIT_FAILURE);
return EXIT_FAILURE;
}
display_mime(mime);
mailmime_free(mime);
free(data);
exit(status);
exit(EXIT_SUCCESS);
}

Loading…
Cancel
Save