Browse Source

...

async_key_management
vb 7 years ago
parent
commit
8af48b626a
10 changed files with 729 additions and 209 deletions
  1. +101
    -0
      src/etpan_mime.c
  2. +20
    -1
      src/etpan_mime.h
  3. +10
    -4
      src/message_api.c
  4. +291
    -120
      src/mime.c
  5. +12
    -22
      src/mime.h
  6. +1
    -1
      src/platform_windows.h
  7. +43
    -7
      src/transport.c
  8. +13
    -9
      src/transport.h
  9. +223
    -26
      src/wrappers.h
  10. +15
    -19
      test/mime_test.cc

+ 101
- 0
src/etpan_mime.c View File

@ -1,12 +1,15 @@
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include "etpan_mime.h"
#ifndef mailmime_param_new_with_data
#include <libetpan/mailprivacy_tools.h>
#endif
time_t mail_mkgmtime(struct tm * tmp);
#define MAX_MESSAGE_ID 512
static char * generate_boundary(const char * boundary_prefix)
@ -242,3 +245,101 @@ err:
return NULL;
}
struct mailimf_field * _new_field(
int type,
_new_func_t new_func,
void *value
)
{
void *data = new_func(value);
assert(data);
if (data == NULL)
return NULL;
struct mailimf_field * result = calloc(1, sizeof(struct mailimf_field));
assert(result);
if (result == NULL) {
free(data);
return NULL;
}
result->fld_type = type;
result->fld_data.fld_return_path = data;
return result;
}
void _free_field(struct mailimf_field *field)
{
if (field)
free(field->fld_data.fld_return_path);
free(field);
}
int _append_field(
clist *list,
int type,
_new_func_t new_func,
void *value
)
{
int r;
struct mailimf_field * field;
assert(list);
assert(new_func);
assert(value);
field = _new_field(type, new_func, value);
if (field == NULL)
return -1;
r = clist_append(list, field);
if (r == -1)
_free_field(field);
return r;
}
struct mailimf_date_time * timestamp_to_etpantime(const struct tm *ts)
{
struct mailimf_date_time * result = calloc(1,
sizeof(struct mailimf_date_time));
assert(result);
if (result == NULL)
return NULL;
assert(ts);
result->dt_sec = ts->tm_sec;
result->dt_min = ts->tm_min;
result->dt_hour = ts->tm_hour;
result->dt_day = ts->tm_mday;
result->dt_month = ts->tm_mon + 1;
result->dt_year = ts->tm_year + 1900;
result->dt_zone = (int) (ts->tm_gmtoff / 36L);
return result;
}
struct tm * etpantime_to_timestamp(const struct mailimf_date_time *et)
{
struct tm * result = calloc(1, sizeof(struct tm));
assert(result);
if (result == NULL)
return NULL;
assert(et);
result->tm_sec = et->dt_sec;
result->tm_min = et->dt_min;
result->tm_hour = et->dt_hour;
result->tm_mday = et->dt_day;
result->tm_mon = et->dt_month - 1;
result->tm_year = et->dt_year - 1900;
result->tm_gmtoff = 36L * (long) et->dt_zone;
return result;
}

+ 20
- 1
src/etpan_mime.h View File

@ -2,7 +2,6 @@
#include <libetpan/libetpan.h>
struct mailmime * part_new_empty(
struct mailmime_content * content,
struct mailmime_fields * mime_fields,
@ -29,3 +28,23 @@ struct mailmime * part_multiple_new(
const char * boundary_prefix
);
typedef void *(*_new_func_t)(void *);
struct mailimf_field * _new_field(
int type,
_new_func_t new_func,
void *value
);
void _free_field(struct mailimf_field *field);
int _append_field(
clist *list,
int type,
_new_func_t new_func,
void *value
);
struct mailimf_date_time * timestamp_to_etpantime(const struct tm *ts);
struct tm * etpantime_to_timestamp(const struct mailimf_date_time *et);

+ 10
- 4
src/message_api.c View File

@ -248,12 +248,18 @@ DYNAMIC_API PEP_STATUS encrypt_message(
}
if (src->enc_format == PEP_enc_none) {
char *_ptext = ptext;
status = mime_encode_text(_ptext, src->longmsg_formatted,
src->attachments, &ptext);
message *_src = (message *) malloc(sizeof(message));
assert(_src);
if (_src == NULL)
goto enomem;
memcpy(_src, src, sizeof(message));
_src->shortmsg = "pEp";
_src->longmsg = ptext;
status = mime_encode_message(src, &ptext);
assert(status == PEP_STATUS_OK);
if (free_ptext)
free(_ptext);
free(_src->longmsg);
free(_src);
assert(ptext);
if (ptext == NULL)
goto pep_error;


+ 291
- 120
src/mime.c View File

@ -10,124 +10,22 @@
#include "etpan_mime.h"
#include "wrappers.h"
DYNAMIC_API PEP_STATUS mime_encode_text(
const char *plaintext,
const char *htmltext,
bloblist_t *attachments,
char **mimetext
)
static PEP_STATUS render_mime(struct mailmime *mime, char **mimetext)
{
struct mailmime * mime = NULL;
struct mailmime * submime = NULL;
int col;
int r;
PEP_STATUS status = PEP_STATUS_OK;
int fd;
FILE *file = NULL;
size_t size;
char *buf = NULL;
PEP_STATUS status;
assert(plaintext);
assert(mimetext);
*mimetext = NULL;
if (htmltext) {
mime = part_multiple_new("multipart/alternative", NULL);
assert(mime);
if (mime == NULL)
goto enomem;
submime = get_text_part("text/plain", plaintext, strlen(plaintext),
MAILMIME_MECHANISM_QUOTED_PRINTABLE);
assert(submime);
if (submime == NULL)
goto enomem;
r = mailmime_smart_add_part(mime, submime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY) {
goto enomem;
}
else {
// mailmime_smart_add_part() takes ownership of submime
submime = NULL;
}
submime = get_text_part("text/html", htmltext, strlen(htmltext),
MAILMIME_MECHANISM_QUOTED_PRINTABLE);
assert(submime);
if (submime == NULL)
goto enomem;
r = mailmime_smart_add_part(mime, submime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY)
goto enomem;
else {
// mailmime_smart_add_part() takes ownership of submime
submime = NULL;
}
}
else {
mime = get_text_part("text/plain", plaintext, strlen(plaintext),
MAILMIME_MECHANISM_QUOTED_PRINTABLE);
assert(mime);
if (mime == NULL)
goto enomem;
}
if (attachments) {
submime = mime;
mime = part_multiple_new("multipart/mixed", NULL);
assert(mime);
if (mime == NULL)
goto enomem;
r = mailmime_smart_add_part(mime, submime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY) {
goto enomem;
}
else {
// mailmime_smart_add_part() takes ownership of submime
submime = NULL;
}
bloblist_t *_a;
for (_a = attachments; _a != NULL; _a = _a->next) {
char * mime_type;
assert(_a->data);
assert(_a->size);
if (_a->mime_type == NULL)
mime_type = "application/octet-stream";
else
mime_type = _a->mime_type;
submime = get_file_part(_a->file_name, mime_type, _a->data, _a->size);
assert(submime);
if (submime == NULL)
goto enomem;
r = mailmime_smart_add_part(mime, submime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY) {
goto enomem;
}
else {
// mailmime_smart_add_part() takes ownership of submime
submime = NULL;
}
}
}
int col;
int r;
char *template = strdup("/tmp/pEp.XXXXXXXXXXXXXXXXXXXX");
assert(template);
if (template == NULL)
goto enomem;
*mimetext = NULL;
fd = Mkstemp(template);
assert(fd != -1);
if (fd == -1)
@ -190,13 +88,12 @@ DYNAMIC_API PEP_STATUS mime_encode_text(
goto enomem;
size_t _read;
_read = Fread1(buf, size, file);
_read = Fread(buf, size, 1, file);
assert(_read == size);
r = Fclose(file);
assert(r == 0);
mailmime_free(mime);
*mimetext = buf;
return PEP_STATUS_OK;
@ -224,38 +121,312 @@ pep_error:
assert(r == 0);
}
return status;
}
static PEP_STATUS mime_html_text(
const char *plaintext,
const char *htmltext,
struct mailmime **result
)
{
PEP_STATUS status = PEP_STATUS_OK;
struct mailmime * mime = NULL;
struct mailmime * submime = NULL;
int r;
assert(plaintext);
assert(htmltext);
assert(result);
*result = NULL;
mime = part_multiple_new("multipart/alternative", NULL);
assert(mime);
if (mime == NULL)
goto enomem;
submime = get_text_part("text/plain", plaintext, strlen(plaintext),
MAILMIME_MECHANISM_QUOTED_PRINTABLE);
assert(submime);
if (submime == NULL)
goto enomem;
r = mailmime_smart_add_part(mime, submime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY) {
goto enomem;
}
else {
// mailmime_smart_add_part() takes ownership of submime
submime = NULL;
}
submime = get_text_part("text/html", htmltext, strlen(htmltext),
MAILMIME_MECHANISM_QUOTED_PRINTABLE);
assert(submime);
if (submime == NULL)
goto enomem;
r = mailmime_smart_add_part(mime, submime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY)
goto enomem;
else {
// mailmime_smart_add_part() takes ownership of submime
submime = NULL;
}
*result = mime;
return PEP_STATUS_OK;
enomem:
status = PEP_OUT_OF_MEMORY;
pep_error:
if (mime)
mailmime_free(mime);
if (submime)
mailmime_free(submime);
return status;
}
static PEP_STATUS mime_attachment(
bloblist_t *blob,
struct mailmime **result
)
{
PEP_STATUS status = PEP_STATUS_OK;
struct mailmime * mime = NULL;
char * mime_type;
assert(blob);
assert(result);
*result = NULL;
if (blob->mime_type == NULL)
mime_type = "application/octet-stream";
else
mime_type = blob->mime_type;
mime = get_file_part(blob->file_name, mime_type, blob->data, blob->size);
assert(mime);
if (mime == NULL)
goto enomem;
*result = mime;
return PEP_STATUS_OK;
enomem:
status = PEP_OUT_OF_MEMORY;
pep_error:
if (mime)
mailmime_free(mime);
return status;
}
static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **result)
{
PEP_STATUS status = PEP_STATUS_OK;
struct mailimf_fields * fields = NULL;
int r;
clist * list;
clist * fields_list = NULL;
char *subject = msg->shortmsg ? msg->shortmsg : "pEp";
assert(msg);
assert(msg->from);
assert(msg->from->address);
assert(result);
*result = NULL;
fields_list = clist_new();
assert(fields_list);
if (fields_list == NULL)
goto enomem;
r = _append_field(fields_list, MAILIMF_FIELD_MESSAGE_ID,
(_new_func_t) mailimf_message_id_new, msg->id);
if (r == -1)
goto enomem;
r = _append_field(fields_list, MAILIMF_FIELD_SUBJECT,
(_new_func_t) mailimf_subject_new, subject);
if (r == -1)
goto enomem;
fields = mailimf_fields_new(fields_list);
assert(fields);
if (fields == NULL)
goto enomem;
*result = fields;
return PEP_STATUS_OK;
enomem:
status = PEP_OUT_OF_MEMORY;
pep_error:
if (fields_list)
clist_free(fields_list);
if (fields)
mailimf_fields_free(fields);
return status;
}
DYNAMIC_API PEP_STATUS mime_encode_message(
const message *msg,
char **mimetext
)
{
struct mailmime * msg_mime = NULL;
struct mailmime * mime = NULL;
struct mailmime * submime = NULL;
char *buf = NULL;
int r;
PEP_STATUS status;
char *subject;
char *plaintext;
char *htmltext;
assert(msg);
assert(mimetext);
*mimetext = NULL;
subject = (msg->shortmsg) ? msg->shortmsg : "pEp";
plaintext = (msg->longmsg) ? msg->longmsg : "";
htmltext = msg->longmsg_formatted;
if (htmltext) {
status = mime_html_text(plaintext, htmltext, &mime);
if (status != PEP_STATUS_OK)
goto pep_error;
}
else {
mime = get_text_part("text/plain", msg->longmsg, strlen(msg->longmsg),
MAILMIME_MECHANISM_QUOTED_PRINTABLE);
assert(mime);
if (mime == NULL)
goto enomem;
}
if (msg->attachments) {
submime = mime;
mime = part_multiple_new("multipart/mixed", NULL);
assert(mime);
if (mime == NULL)
goto enomem;
r = mailmime_smart_add_part(mime, submime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY) {
goto enomem;
}
else {
// mailmime_smart_add_part() takes ownership of submime
submime = NULL;
}
bloblist_t *_a;
for (_a = msg->attachments; _a != NULL; _a = _a->next) {
char * mime_type;
assert(_a->data);
assert(_a->size);
status = mime_attachment(_a, &submime);
if (status != PEP_STATUS_OK)
goto pep_error;
r = mailmime_smart_add_part(mime, submime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY) {
goto enomem;
}
else {
// mailmime_smart_add_part() takes ownership of submime
submime = NULL;
}
}
}
msg_mime = mailmime_new_message_data(NULL);
mailmime_add_part(msg_mime, mime);
status = render_mime(mime, &buf);
if (status != PEP_STATUS_OK)
goto pep_error;
mailmime_free(msg_mime);
*mimetext = buf;
return PEP_STATUS_OK;
enomem:
status = PEP_OUT_OF_MEMORY;
pep_error:
if (msg_mime)
mailmime_free(mime);
else
if (mime)
mailmime_free(mime);
if (submime)
mailmime_free(submime);
return status;
}
DYNAMIC_API PEP_STATUS mime_decode_text(
DYNAMIC_API PEP_STATUS mime_decode_message(
const char *mimetext,
char **plaintext,
char **htmltext,
bloblist_t **attachments
message **msg
)
{
PEP_STATUS status = PEP_STATUS_OK;
struct mailmime * mime = NULL;
int r;
assert(mimetext);
assert(plaintext);
assert(htmltext);
assert(attachments);
assert(msg);
*plaintext = NULL;
*htmltext = NULL;
*attachments = NULL;
*msg = NULL;
size_t index = 0;
r = mailmime_parse(mimetext, strlen(mimetext), &index, &mime);
assert(r == 0);
assert(mime);
if (r != 0) {
if (r == MAILIMF_ERROR_MEMORY)
goto enomem;
else
goto err_mime;
}
mailmime_free(mime);
return status;
err_mime:
status = PEP_ILLEGAL_VALUE;
goto pep_error;
enomem:
status = PEP_OUT_OF_MEMORY;
pep_error:
if (mime)
mailmime_free(mime);
return status;
}

+ 12
- 22
src/mime.h View File

@ -7,13 +7,10 @@ extern "C" {
#endif
// mime_encode_text() - encode a MIME message
// mime_encode_message() - encode a MIME message
//
// parameters:
// plaintext (in) plaintext of message as UTF-8 string
// htmltext (in) optional HTML version of message as UTF-8
// string or NULL if it does not apply
// attachments (in) attatchments or NULL if there are none
// msg (in) message to encode
// mimetext (out) the resulting encoded text or NULL on any error
//
// return value:
@ -26,25 +23,20 @@ extern "C" {
// PEP_OUT_OF_MEMORY if not enough memory could be allocated
//
// caveat:
// the resulttext will go to the ownership of the caller; plaintext,
// htmltext and attachments will remain in the ownership of the caller
// the resulttext will go to the ownership of the caller
// the message will remain in the ownership of the caller
DYNAMIC_API PEP_STATUS mime_encode_text(
const char *plaintext,
const char *htmltext,
bloblist_t *attachments,
DYNAMIC_API PEP_STATUS mime_encode_message(
const message * msg,
char **mimetext
);
// mime_decode_text() - decode a MIME message
// mime_decode_message() - decode a MIME message
//
// parameters:
// mimetext (in) MIME encoded text to decode
// plaintext (out) plaintext of message as UTF-8 string
// htmltext (out) optional HTML version of message as UTF-8
// string or NULL if it does not apply
// attachments (out) attatchments or NULL if there are none
// msg (out) decoded message
//
// return value:
// PEP_STATUS_OK if everything worked
@ -56,14 +48,12 @@ DYNAMIC_API PEP_STATUS mime_encode_text(
// PEP_OUT_OF_MEMORY if not enough memory could be allocated
//
// caveat:
// plaintext, htmltext and attachments will go to the ownership of the
// caller; mimetext will remain in the ownership of the caller
// the decoded message will go to the ownership of the caller; mimetext
// will remain in the ownership of the caller
DYNAMIC_API PEP_STATUS mime_decode_text(
DYNAMIC_API PEP_STATUS mime_decode_message(
const char *mimetext,
char **plaintext,
char **htmltext,
bloblist_t **attachments
message **msg
);
#ifdef __cplusplus


+ 1
- 1
src/platform_windows.h View File

@ -18,7 +18,7 @@ void *dlsym(void *handle, const char *symbol);
#define strdup(A) _strdup(A)
#endif
#ifndef snprintf
#define snprintf _snprintf
#define snprintf(...) _snprintf(__VA_ARGS__)
#endif
#ifndef strtok_r
#define strtok_r(A, B, C) strtok_s((A), (B), (C))


+ 43
- 7
src/transport.c View File

@ -229,13 +229,18 @@ DYNAMIC_API void free_message(message *msg)
free(msg->longmsg);
free(msg->longmsg_formatted);
free_bloblist(msg->attachments);
free(msg->sent);
free(msg->recv);
free_identity(msg->from);
free_identity_list(msg->to);
free_identity(msg->recv_by);
free_identity_list(msg->cc);
free_identity_list(msg->bcc);
free_identity(msg->reply_to);
free(msg->refering_id);
free(msg->in_reply_to);
free_stringlist(msg->references);
free_stringlist(msg->keywords);
free(msg->comments);
free(msg);
}
}
@ -289,8 +294,20 @@ DYNAMIC_API message * message_dup(const message *src)
msg->rawmsg_ref = src->rawmsg_ref;
msg->rawmsg_size = src->rawmsg_size;
msg->sent = src->sent;
msg->recv = src->recv;
if (src->sent) {
msg->sent = malloc(sizeof(timestamp));
if (msg->sent == NULL)
goto enomem;
memcpy(msg->sent, src->sent, sizeof(timestamp));
}
if (src->recv) {
msg->recv = malloc(sizeof(timestamp));
if (msg->recv == NULL)
goto enomem;
memcpy(msg->recv, src->recv, sizeof(timestamp));
}
if (src->recv_by) {
msg->recv_by = identity_dup(src->recv_by);
@ -316,21 +333,40 @@ DYNAMIC_API message * message_dup(const message *src)
goto enomem;
}
if (src->refering_id) {
msg->refering_id = strdup(src->refering_id);
assert(msg->refering_id);
if (msg->refering_id == NULL)
if (src->in_reply_to) {
msg->in_reply_to = strdup(src->in_reply_to);
assert(msg->in_reply_to);
if (msg->in_reply_to == NULL)
goto enomem;
}
msg->refering_msg_ref = src->refering_msg_ref;
if (src->references) {
msg->references = stringlist_dup(src->references);
if (msg->references == NULL)
goto enomem;
}
if (src->refered_by) {
msg->refered_by = message_ref_list_dup(src->refered_by);
if (msg->refered_by == NULL)
goto enomem;
}
if (src->keywords) {
msg->keywords = stringlist_dup(src->keywords);
if (msg->keywords == NULL)
goto enomem;
}
if (src->comments) {
msg->comments = strdup(src->comments);
assert(msg->comments);
if (msg->comments == NULL)
goto enomem;
}
msg->enc_format = src->enc_format;
return msg;


+ 13
- 9
src/transport.h View File

@ -180,17 +180,17 @@ struct _message_ref_list;
typedef struct _message {
PEP_msg_direction dir;
char * id; // UTF-8 string of message ID
char * shortmsg; // UTF-8 string of short message
char * longmsg; // UTF-8 string of long message
char *id; // UTF-8 string of message ID
char *shortmsg; // UTF-8 string of short message
char *longmsg; // UTF-8 string of long message
// (plain)
char * longmsg_formatted; // UTF-8 string of long message
char *longmsg_formatted; // UTF-8 string of long message
// (formatted)
bloblist_t * attachments; // blobs with attachements
char * rawmsg_ref; // reference to raw message data
bloblist_t *attachments; // blobs with attachements
char *rawmsg_ref; // reference to raw message data
size_t rawmsg_size; // size of raw message data
timestamp sent; // when the message is sent
timestamp recv; // when the message is received
timestamp *sent; // when the message is sent
timestamp *recv; // when the message is received
pEp_identity *from; // whom the message is from
identity_list *to; // whom the message is to
pEp_identity *recv_by; // via which identity the message
@ -198,10 +198,14 @@ typedef struct _message {
identity_list *cc; // whom a CC is being sent
identity_list *bcc; // whom a BCC is being sent
pEp_identity *reply_to; // where a reply should go to
char * refering_id; // UTF-8 string of refering message ID
char *in_reply_to; // UTF-8 string with MessageID of
// refering message
struct _message *refering_msg_ref; // reference to refering message
stringlist_t *references; // list of UTF-8 strings with references
struct _message_ref_list *refered_by; // list of references to messages being
// refered
stringlist_t *keywords; // list of UTF-8 strings with keywords
char *comments; // UTF-8 string with comments
PEP_enc_format enc_format; // format of encrypted data
} message;


+ 223
- 26
src/wrappers.h View File

@ -2,8 +2,8 @@
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <unistd.h>
#ifdef EOF // stdio.h
static inline FILE * Fopen(const char *filename, const char *mode)
{
@ -15,6 +15,19 @@ static inline FILE * Fopen(const char *filename, const char *mode)
return f;
}
#define fopen >@<
static inline FILE * Fdopen(int fildes, const char *mode)
{
FILE * f;
do {
f = fdopen(fildes, mode);
} while (f == NULL && errno == EINTR);
return f;
}
#define fdopen >@<
static inline char *Fgets(char * str, int size, FILE * stream)
{
@ -26,6 +39,19 @@ static inline char *Fgets(char * str, int size, FILE * stream)
return s;
}
#define fgets >@<
static inline int Fputs(const char *str, FILE * stream)
{
int r;
do {
r = fputs(str, stream);
} while (r == EOF && errno == EINTR);
return r;
}
#define fputs >@<
static inline int Fclose(FILE *stream)
{
@ -33,10 +59,11 @@ static inline int Fclose(FILE *stream)
do {
r = fclose(stream);
} while (r == -1 && errno == EINTR);
} while (r == EOF && errno == EINTR);
return r;
}
#define fclose >@<
static inline FILE * Freopen(
const char *filename,
@ -52,6 +79,7 @@ static inline FILE * Freopen(
return f;
}
#define freopen >@<
static inline int Fprintf(FILE * stream, const char * format, ...)
{
@ -68,6 +96,53 @@ static inline int Fprintf(FILE * stream, const char * format, ...)
return n;
}
#define fprintf >@<
static inline size_t Fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream)
{
size_t r = 0;
do {
clearerr(stream);
size_t n = fwrite((char *) ptr + r, size, nitems, stream);
nitems -= n;
r += n * size;
} while (nitems && ferror(stream) == EINTR);
return r;
}
#define fwrite >@<
static inline size_t Fread(void *ptr, size_t size, size_t nitems, FILE *stream)
{
size_t r = 0;
do {
clearerr(stream);
size_t n = fread((char *) ptr + r, size, nitems, stream);
nitems -= n;
r += n * size;
} while (!feof(stream) && nitems && ferror(stream) == EINTR);
return r;
}
#define fread >@<
static inline int Fflush(FILE *stream)
{
int r;
do {
r = fflush(stream);
} while (r == -1 && errno == EINTR);
return r;
}
#define fflush >@<
#endif // stdio.h
#ifdef F_OK // unistd.h
static inline int Mkstemp(char *template)
{
@ -79,51 +154,173 @@ static inline int Mkstemp(char *template)
return fd;
}
#define mkstemp >@<
static inline FILE * Fdopen(int fildes, const char *mode)
static inline int Close(int fildes)
{
FILE * f;
int r;
do {
f = fdopen(fildes, mode);
} while (f == NULL && errno == EINTR);
r = close(fildes);
} while (r == -1 && errno == EINTR);
return f;
return r;
}
#define close >@<
static inline int Close(int fildes)
static inline ssize_t Write(int fildes, const void *buf, size_t nbyte)
{
ssize_t r;
do {
r = write(fildes, buf, nbyte);
} while (r == -1 && errno == EINTR);
return r;
}
#define write >@<
static inline ssize_t Read(int fildes, void *buf, size_t nbyte)
{
ssize_t r;
do {
r = read(fildes, buf, nbyte);
} while (r == -1 && errno == EINTR);
return r;
}
#define read >@<
static inline int Ftruncate(int fildes, off_t length)
{
int r;
do {
r = close(fildes);
r = ftruncate(fildes, length);
} while (r == -1 && errno == EINTR);
return r;
}
#define ftruncate >@<
static inline size_t Fread1(void *ptr, size_t size, FILE *stream)
static inline int Dup2(int fildes, int fildes2)
{
char *_buf = ptr;
size_t rest = size;
size_t bytes_read;
int fd;
for (bytes_read = 0; rest > 0; _buf += rest) {
clearerr(stream);
do {
fd = dup2(fildes, fildes2);
} while (fd == -1 && errno == EINTR);
bytes_read = rest * fread(_buf, rest, 1, stream);
rest -= bytes_read;
return fd;
}
#define dup2 >@<
if (ferror(stream) != 0 && ferror(stream) != EINTR)
goto err_file;
#endif
if (feof(stream))
goto err_file;
}
#ifdef FD_CLR // select.h
return size;
static inline int Select(
int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *errorfds,
struct timeval *timeout
)
{
int r;
err_file:
return size - rest;
do {
r = select(nfds, readfds, writefds, errorfds, timeout);
} while (r == -1 && errno == EINTR);
return r;
}
#define select >@<
#endif // select.h
#ifdef F_SETLKW // fcntl.h
static inline int Fcntl(int fildes, int cmd, void *structure)
{
int r;
do {
r = fcntl(fildes, cmd, structure);
} while (r == -1 && errno == EINTR);
return r;
}
// fnctl does only risk EINTR if cmd == F_SETLKW
static inline int Open(const char *path, int oflag, ...)
{
int fd;
do {
fd = open(path, oflag, 0);
} while (fd == -1 && errno == EINTR);
return fd;
}
#define open >@<
static inline int Creat(const char *path, mode_t mode)
{
int fd;
do {
fd = creat(path, mode);
} while (fd == -1 && errno == EINTR);
return fd;
}
#define creat >@<
#endif // fcntl.h
#ifdef MSG_PEEK // socket.h
static inline ssize_t Recv(int socket, void *buffer, size_t length, int flags)
{
ssize_t r;
do {
r = recv(socket, buffer, length, flags);
} while (r == -1 && errno == EINTR);
return r;
}
#define recv >@<
static inline ssize_t Send(int socket, const void *buffer, size_t length, int flags)
{
ssize_t r;
do {
r = send(socket, buffer, length, flags);
} while (r == -1 && errno == EINTR);
return r;
}
#define send >@<
#endif // socket.h
#ifdef WNOHANG // wait.h
static inline pid_t Waitpid(pid_t pid, int *stat_loc, int options)
{
pid_t r;
do {
r = waitpid(pid, stat_loc, options);
} while (r == -1 && errno == EINTR);
return r;
}
#define waitpid >@<
#endif

+ 15
- 19
test/mime_test.cc View File

@ -1,4 +1,5 @@
#include <iostream>
#include <fstream>
#include <string>
#include <assert.h>
#include "mime.h"
@ -18,12 +19,22 @@ int main() {
// mime test code
// testing plain
// testing multipart/alternative
message *msg2 = new_message(PEP_dir_incoming,
new_identity("vb@dingens.org", NULL, NULL, NULL),
new_identity_list(new_identity("trischa@dingens.org", NULL, NULL, NULL)),
"my sübject");
assert(msg2);
string text2 = "my mèssage to yoü";
msg2->longmsg = strdup(text2.c_str());
string html2 = "<html><body><p>my message to you</p></body></html>";
msg2->longmsg_formatted = strdup(html2.c_str());
assert(msg2->longmsg_formatted);
string bla2 = "my message to yöu";
cout << "encoding message…\n";
char *result2;
PEP_STATUS status2 = mime_encode_text(bla2.c_str(), NULL, NULL, &result2);
PEP_STATUS status2 = mime_encode_message(msg2, &result2);
assert(result2);
assert(status2 == PEP_STATUS_OK);
@ -31,22 +42,7 @@ int main() {
cout << result2 << "\n";
free(result2);
// testing multipart/alternative
string bla3 = "my message to yöu";
string html3 = "<html><body><p>my message to you</p></body></html>";
cout << "encoding message…\n";
char *result3;
PEP_STATUS status3 = mime_encode_text(bla3.c_str(), html3.c_str(), NULL, &result3);
assert(result3);
assert(status3 == PEP_STATUS_OK);
cout << "result:\n";
cout << result3 << "\n";
free(result3);
free_message(msg2);
cout << "calling release()\n";
release(session);


Loading…
Cancel
Save