libetpan - fdik
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

377 lines
8.3 KiB

#include <libetpan/libetpan.h>
#include <sys/stat.h>
#include <stdlib.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_type) {
case MAILMIME_DATA_TEXT:
printf("data : %u bytes\n", (unsigned int) data->dt_data.dt_text.dt_length);
break;
case MAILMIME_DATA_FILE:
printf("data (file) : %s\n", data->dt_data.dt_filename);
break;
}
}
static void display_mime_parameter(struct mailmime_parameter * param)
{
printf("%s = %s\n", param->pa_name, param->pa_value);
}
static void display_mime_dsp_parm(struct mailmime_disposition_parm * param)
{
switch (param->pa_type) {
case MAILMIME_DISPOSITION_PARM_FILENAME:
printf("filename: %s\n", param->pa_data.pa_filename);
break;
}
}
static void display_mime_disposition(struct mailmime_disposition * disposition)
{
clistiter * cur;
for(cur = clist_begin(disposition->dsp_parms) ;
cur != NULL ; cur = clist_next(cur)) {
struct mailmime_disposition_parm * param;
param = clist_content(cur);
display_mime_dsp_parm(param);
}
}
static void display_mime_field(struct mailmime_field * field)
{
switch (field->fld_type) {
case MAILMIME_FIELD_TYPE:
printf("content-type: ");
display_mime_content(field->fld_data.fld_content);
printf("\n");
break;
case MAILMIME_FIELD_DISPOSITION:
display_mime_disposition(field->fld_data.fld_disposition);
break;
}
}
static void display_mime_fields(struct mailmime_fields * fields)
{
clistiter * cur;
for(cur = clist_begin(fields->fld_list) ; cur != NULL ; cur = clist_next(cur)) {
struct mailmime_field * field;
field = clist_content(cur);
display_mime_field(field);
}
}
static void display_date_time(struct mailimf_date_time * d)
{
printf("%02i/%02i/%i %02i:%02i:%02i %+04i",
d->dt_day, d->dt_month, d->dt_year,
d->dt_hour, d->dt_min, d->dt_sec, d->dt_zone);
}
static void display_orig_date(struct mailimf_orig_date * orig_date)
{
display_date_time(orig_date->dt_date_time);
}
static void display_mailbox(struct mailimf_mailbox * mb)
{
if (mb->mb_display_name != NULL)
printf("%s ", mb->mb_display_name);
printf("<%s>", mb->mb_addr_spec);
}
static void display_mailbox_list(struct mailimf_mailbox_list * mb_list)
{
clistiter * cur;
for(cur = clist_begin(mb_list->mb_list) ; cur != NULL ;
cur = clist_next(cur)) {
struct mailimf_mailbox * mb;
mb = clist_content(cur);
display_mailbox(mb);
if (clist_next(cur) != NULL) {
printf(", ");
}
}
}
static void display_group(struct mailimf_group * group)
{
clistiter * cur;
printf("%s: ", group->grp_display_name);
for(cur = clist_begin(group->grp_mb_list->mb_list) ; cur != NULL ; cur = clist_next(cur)) {
struct mailimf_mailbox * mb;
mb = clist_content(cur);
display_mailbox(mb);
}
printf("; ");
}
static void display_address(struct mailimf_address * a)
{
switch (a->ad_type) {
case MAILIMF_ADDRESS_GROUP:
display_group(a->ad_data.ad_group);
break;
case MAILIMF_ADDRESS_MAILBOX:
display_mailbox(a->ad_data.ad_mailbox);
break;
}
}
static void display_address_list(struct mailimf_address_list * addr_list)
{
clistiter * cur;
for(cur = clist_begin(addr_list->ad_list) ; cur != NULL ;
cur = clist_next(cur)) {
struct mailimf_address * addr;
addr = clist_content(cur);
display_address(addr);
if (clist_next(cur) != NULL) {
printf(", ");
}
}
}
static void display_from(struct mailimf_from * from)
{
display_mailbox_list(from->frm_mb_list);
}
static void display_to(struct mailimf_to * to)
{
display_address_list(to->to_addr_list);
}
static void display_cc(struct mailimf_cc * cc)
{
display_address_list(cc->cc_addr_list);
}
static void display_subject(struct mailimf_subject * subject)
{
printf("%s", subject->sbj_value);
}
static void display_field(struct mailimf_field * field)
{
switch (field->fld_type) {
case MAILIMF_FIELD_ORIG_DATE:
printf("Date: ");
display_orig_date(field->fld_data.fld_orig_date);
printf("\n");
break;
case MAILIMF_FIELD_FROM:
printf("From: ");
display_from(field->fld_data.fld_from);
printf("\n");
break;
case MAILIMF_FIELD_TO:
printf("To: ");
display_to(field->fld_data.fld_to);
printf("\n");
break;
case MAILIMF_FIELD_CC:
printf("Cc: ");
display_cc(field->fld_data.fld_cc);
printf("\n");
break;
case MAILIMF_FIELD_SUBJECT:
printf("Subject: ");
display_subject(field->fld_data.fld_subject);
printf("\n");
break;
case MAILIMF_FIELD_MESSAGE_ID:
printf("Message-ID: %s\n", field->fld_data.fld_message_id->mid_value);
break;
}
}
static void display_fields(struct mailimf_fields * fields)
{
clistiter * cur;
for(cur = clist_begin(fields->fld_list) ; cur != NULL ;
cur = clist_next(cur)) {
struct mailimf_field * f;
f = clist_content(cur);
display_field(f);
}
}
static void display_mime_discrete_type(struct mailmime_discrete_type * discrete_type)
{
switch (discrete_type->dt_type) {
case MAILMIME_DISCRETE_TYPE_TEXT:
printf("text");
break;
case MAILMIME_DISCRETE_TYPE_IMAGE:
printf("image");
break;
case MAILMIME_DISCRETE_TYPE_AUDIO:
printf("audio");
break;
case MAILMIME_DISCRETE_TYPE_VIDEO:
printf("video");
break;
case MAILMIME_DISCRETE_TYPE_APPLICATION:
printf("application");
break;
case MAILMIME_DISCRETE_TYPE_EXTENSION:
printf("%s", discrete_type->dt_extension);
break;
}
}
static void display_mime_composite_type(struct mailmime_composite_type * ct)
{
switch (ct->ct_type) {
case MAILMIME_COMPOSITE_TYPE_MESSAGE:
printf("message");
break;
case MAILMIME_COMPOSITE_TYPE_MULTIPART:
printf("multipart");
break;
case MAILMIME_COMPOSITE_TYPE_EXTENSION:
printf("%s", ct->ct_token);
break;
}
}
static void display_mime_type(struct mailmime_type * type)
{
switch (type->tp_type) {
case MAILMIME_TYPE_DISCRETE_TYPE:
display_mime_discrete_type(type->tp_data.tp_discrete_type);
break;
case MAILMIME_TYPE_COMPOSITE_TYPE:
display_mime_composite_type(type->tp_data.tp_composite_type);
break;
}
}
static void display_mime_content(struct mailmime_content * content_type)
{
printf("type: ");
display_mime_type(content_type->ct_type);
printf("/%s\n", content_type->ct_subtype);
}
static void display_mime(struct mailmime * mime)
{
clistiter * cur;
switch (mime->mm_type) {
case MAILMIME_SINGLE:
printf("single part\n");
break;
case MAILMIME_MULTIPLE:
printf("multipart\n");
break;
case MAILMIME_MESSAGE:
printf("message\n");
break;
}
if (mime->mm_mime_fields != NULL) {
if (clist_begin(mime->mm_mime_fields->fld_list) != NULL) {
printf("MIME headers begin\n");
display_mime_fields(mime->mm_mime_fields);
printf("MIME headers end\n");
}
}
display_mime_content(mime->mm_content_type);
switch (mime->mm_type) {
case MAILMIME_SINGLE:
display_mime_data(mime->mm_data.mm_single);
break;
case MAILMIME_MULTIPLE:
for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) {
display_mime(clist_content(cur));
}
break;
case MAILMIME_MESSAGE:
if (mime->mm_data.mm_message.mm_fields) {
if (clist_begin(mime->mm_data.mm_message.mm_fields->fld_list) != NULL) {
printf("headers begin\n");
display_fields(mime->mm_data.mm_message.mm_fields);
printf("headers end\n");
}
if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
display_mime(mime->mm_data.mm_message.mm_msg_mime);
}
break;
}
}
}
int main(int argc, char ** argv)
{
FILE * f;
int r;
struct mailmime * mime;
struct stat stat_info;
char * data;
size_t current_index;
char * filename;
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);
current_index = 0;
r = mailmime_parse(data, stat_info.st_size,
&current_index, &mime);
if (r != MAILIMF_NO_ERROR) {
free(data);
exit(EXIT_FAILURE);
return EXIT_FAILURE;
}
display_mime(mime);
mailmime_free(mime);
free(data);
exit(EXIT_SUCCESS);
}