src/transport.c
author vb
Tue, 10 Mar 2015 15:45:02 +0100
changeset 97 b855132fb7e3
parent 96 fe4931a0413b
child 98 9e3d28932e7b
permissions -rw-r--r--
new message has X-pEp-Version
vb@28
     1
#include "pEp_internal.h"
vb@46
     2
#include "trans_auto.h"
vb@23
     3
vb@23
     4
#include <memory.h>
vb@23
     5
#include <assert.h>
vb@23
     6
vb@62
     7
PEP_STATUS init_transport_system(PEP_SESSION session, bool in_first)
vb@23
     8
{
vb@62
     9
    static PEP_transport_t transports[PEP_trans__count];
vb@62
    10
    
vb@30
    11
    assert(session);
vb@62
    12
    session->transports = transports;
vb@30
    13
vb@62
    14
    if (in_first) {
vb@62
    15
        assert(PEP_trans__count == 1);
vb@62
    16
        memset(transports, 0, sizeof(PEP_transport_t) * PEP_trans__count);
vb@28
    17
vb@62
    18
        transports[PEP_trans_auto].id = PEP_trans_auto;
vb@62
    19
        transports[PEP_trans_auto].sendto = auto_sendto;
vb@62
    20
        transports[PEP_trans_auto].readnext = auto_readnext;
vb@62
    21
    }
vb@23
    22
vb@23
    23
    return PEP_STATUS_OK;
vb@23
    24
}
vb@28
    25
vb@62
    26
void release_transport_system(PEP_SESSION session, bool out_last)
vb@28
    27
{
vb@30
    28
    assert(session);
vb@28
    29
    // nothing yet
vb@28
    30
}
vb@29
    31
vb@48
    32
DYNAMIC_API identity_list *new_identity_list(pEp_identity *ident)
vb@29
    33
{
vb@29
    34
    identity_list *id_list = calloc(1, sizeof(identity_list));
vb@29
    35
    assert(id_list);
vb@76
    36
    if (id_list == NULL)
vb@29
    37
        return NULL;
vb@29
    38
vb@39
    39
    id_list->ident = ident;
vb@29
    40
vb@29
    41
    return id_list;
vb@29
    42
}
vb@29
    43
vb@48
    44
DYNAMIC_API identity_list *identity_list_dup(const identity_list *src)
vb@37
    45
{
vb@37
    46
    assert(src);
vb@37
    47
vb@40
    48
    identity_list *id_list = new_identity_list(identity_dup(src->ident));
vb@37
    49
    assert(id_list);
vb@37
    50
    if (id_list == NULL)
vb@37
    51
        return NULL;
vb@37
    52
vb@37
    53
    if (src->next) {
vb@37
    54
        id_list->next = identity_list_dup(src->next);
vb@37
    55
        if (id_list->next == NULL) {
vb@37
    56
            free_identity_list(id_list);
vb@37
    57
            return NULL;
vb@37
    58
        }
vb@37
    59
    }
vb@37
    60
vb@37
    61
    return id_list;
vb@37
    62
}
vb@37
    63
vb@48
    64
DYNAMIC_API void free_identity_list(identity_list *id_list)
vb@29
    65
{
vb@29
    66
    if (id_list) {
vb@29
    67
        free_identity_list(id_list->next);
vb@29
    68
        free_identity(id_list->ident);
vb@29
    69
        free(id_list);
vb@29
    70
    }
vb@29
    71
}
vb@29
    72
vb@48
    73
DYNAMIC_API identity_list *identity_list_add(identity_list *id_list, pEp_identity *ident)
vb@29
    74
{
vb@29
    75
    assert(ident);
vb@29
    76
vb@38
    77
    if (id_list == NULL)
vb@38
    78
        return new_identity_list(ident);
vb@38
    79
vb@29
    80
    if (id_list->ident == NULL) {
vb@39
    81
        id_list->ident = ident;
vb@39
    82
        return id_list;
vb@29
    83
    }
vb@29
    84
    else if (id_list->next == NULL) {
vb@29
    85
        id_list->next = new_identity_list(ident);
vb@29
    86
        return id_list->next;
vb@29
    87
    }
vb@29
    88
    else {
vb@29
    89
        return identity_list_add(id_list->next, ident);
vb@29
    90
    }
vb@29
    91
}
vb@29
    92
vb@48
    93
DYNAMIC_API bloblist_t *new_bloblist(char *blob, size_t size, const char *mime_type,
vb@39
    94
        const char *file_name)
vb@38
    95
{
vb@38
    96
    bloblist_t * bloblist = calloc(1, sizeof(bloblist_t));
vb@81
    97
    assert(bloblist);
vb@38
    98
    if (bloblist == NULL)
vb@38
    99
        return NULL;
vb@81
   100
vb@39
   101
    if (mime_type) {
vb@39
   102
        bloblist->mime_type = strdup(mime_type);
vb@39
   103
        if (bloblist->mime_type == NULL) {
vb@39
   104
            free(bloblist);
vb@39
   105
            return NULL;
vb@39
   106
        }
vb@39
   107
    }
vb@81
   108
vb@39
   109
    if (file_name) {
vb@39
   110
        bloblist->file_name = strdup(file_name);
vb@39
   111
        if (bloblist->file_name == NULL) {
vb@39
   112
            free(bloblist->mime_type);
vb@39
   113
            free(bloblist);
vb@39
   114
            return NULL;
vb@39
   115
        }
vb@39
   116
    }
vb@81
   117
vb@41
   118
    bloblist->data = blob;
vb@41
   119
    bloblist->size = size;
vb@81
   120
vb@38
   121
    return bloblist;
vb@38
   122
}
vb@38
   123
vb@48
   124
DYNAMIC_API void free_bloblist(bloblist_t *bloblist)
vb@38
   125
{
vb@39
   126
    if (bloblist) {
vb@39
   127
        if (bloblist->next)
vb@39
   128
            free_bloblist(bloblist->next);
vb@41
   129
        free(bloblist->data);
vb@41
   130
        free(bloblist->mime_type);
vb@41
   131
        free(bloblist->file_name);
vb@39
   132
        free(bloblist);
vb@39
   133
    }
vb@38
   134
}
vb@38
   135
vb@81
   136
DYNAMIC_API bloblist_t *bloblist_dup(const bloblist_t *src)
vb@81
   137
{
vb@81
   138
    bloblist_t *bloblist = NULL;
vb@81
   139
vb@81
   140
    assert(src);
vb@81
   141
vb@81
   142
    bloblist = new_bloblist(src->data, src->size, src->mime_type, src->file_name);
vb@81
   143
    if (bloblist == NULL)
vb@81
   144
        goto enomem;
vb@81
   145
vb@81
   146
    if (src->next) {
vb@81
   147
        bloblist->next = bloblist_dup(src->next);
vb@81
   148
        if (bloblist->next == NULL)
vb@81
   149
            goto enomem;
vb@81
   150
    }
vb@81
   151
vb@81
   152
    return bloblist;
vb@81
   153
vb@81
   154
enomem:
vb@81
   155
    free_bloblist(bloblist);
vb@81
   156
    return NULL;
vb@81
   157
}
vb@81
   158
vb@48
   159
DYNAMIC_API bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t size,
vb@39
   160
        const char *mime_type, const char *file_name)
vb@38
   161
{
vb@38
   162
    assert(blob);
vb@38
   163
vb@38
   164
    if (bloblist == NULL)
vb@39
   165
        return new_bloblist(blob, size, mime_type, file_name);
vb@38
   166
vb@41
   167
    if (bloblist->data == NULL) {
vb@39
   168
        if (mime_type) {
vb@39
   169
            bloblist->mime_type = strdup(mime_type);
vb@39
   170
            if (bloblist->mime_type == NULL) {
vb@39
   171
                free(bloblist);
vb@39
   172
                return NULL;
vb@39
   173
            }
vb@39
   174
        }
vb@39
   175
        if (file_name) {
vb@39
   176
            bloblist->file_name = strdup(file_name);
vb@39
   177
            if (bloblist->file_name == NULL) {
vb@39
   178
                free(bloblist->mime_type);
vb@39
   179
                free(bloblist);
vb@39
   180
                return NULL;
vb@39
   181
            }
vb@39
   182
        }
vb@41
   183
        bloblist->data = blob;
vb@41
   184
        bloblist->size = size;
vb@38
   185
        return bloblist;
vb@38
   186
    }
vb@38
   187
vb@38
   188
    if (bloblist->next == NULL) {
vb@39
   189
        bloblist->next = new_bloblist(blob, size, mime_type, file_name);
vb@38
   190
        return bloblist->next;
vb@38
   191
    }
vb@38
   192
vb@39
   193
    return bloblist_add(bloblist->next, blob, size, mime_type, file_name);
vb@38
   194
}
vb@38
   195
vb@95
   196
DYNAMIC_API stringpair_t * new_stringpair(const char *key, const char *value)
vb@95
   197
{
vb@95
   198
    stringpair_t *pair = NULL;
vb@95
   199
vb@95
   200
    assert(key);
vb@95
   201
    assert(value),
vb@95
   202
vb@95
   203
    pair = calloc(1, sizeof(stringpair_t));
vb@95
   204
    assert(pair);
vb@95
   205
    if (pair == NULL)
vb@95
   206
        goto enomem;
vb@95
   207
vb@95
   208
    pair->key = strdup(key);
vb@95
   209
    assert(pair->key);
vb@95
   210
    if (pair->key == NULL)
vb@95
   211
        goto enomem;
vb@95
   212
vb@95
   213
    pair->value = strdup(value);
vb@95
   214
    assert(pair->value);
vb@95
   215
    if (pair->value == NULL)
vb@95
   216
        goto enomem;
vb@95
   217
vb@95
   218
    return pair;
vb@95
   219
vb@95
   220
enomem:
vb@95
   221
    free_stringpair(pair);
vb@95
   222
    return NULL;
vb@95
   223
}
vb@95
   224
vb@95
   225
DYNAMIC_API void free_stringpair(stringpair_t * pair)
vb@95
   226
{
vb@95
   227
    if (pair) {
vb@95
   228
        free(pair->key);
vb@95
   229
        free(pair->value);
vb@95
   230
        free(pair);
vb@95
   231
    }
vb@95
   232
}
vb@95
   233
vb@95
   234
DYNAMIC_API stringpair_t * stringpair_dup(const stringpair_t *src)
vb@95
   235
{
vb@95
   236
    assert(src);
vb@95
   237
    return new_stringpair(src->key, src->value);
vb@95
   238
}
vb@95
   239
vb@95
   240
DYNAMIC_API stringpair_map_t * new_stringpair_map(const stringpair_t *pair)
vb@95
   241
{
vb@95
   242
    stringpair_map_t *map = NULL;
vb@95
   243
vb@95
   244
    map = calloc(1, sizeof(stringpair_map_t));
vb@95
   245
    assert(map);
vb@95
   246
    if (map == NULL)
vb@95
   247
        goto enomem;
vb@95
   248
vb@95
   249
    if (pair) {
vb@95
   250
        map->pair = stringpair_dup(pair);
vb@95
   251
        if (map->pair == NULL)
vb@95
   252
            goto enomem;
vb@95
   253
    }
vb@95
   254
vb@95
   255
    return map;
vb@95
   256
vb@95
   257
enomem:
vb@95
   258
    free_stringpair_map(map);
vb@95
   259
    return NULL;
vb@95
   260
}
vb@95
   261
vb@95
   262
DYNAMIC_API void free_stringpair_map(stringpair_map_t *map)
vb@95
   263
{
vb@95
   264
    if (map) {
vb@95
   265
        free_stringpair_map(map->left);
vb@95
   266
        free_stringpair_map(map->right);
vb@95
   267
        free_stringpair(map->pair);
vb@95
   268
        free(map);
vb@95
   269
    }
vb@95
   270
}
vb@95
   271
vb@95
   272
static stringpair_map_t * _stringpair_map_dup(
vb@95
   273
        const stringpair_map_t *src,
vb@95
   274
        stringpair_map_t *parent
vb@95
   275
    )
vb@95
   276
{
vb@95
   277
    stringpair_map_t *map = NULL;   
vb@95
   278
vb@95
   279
    assert(src);
vb@95
   280
vb@95
   281
    map = new_stringpair_map(src->pair);
vb@95
   282
    if (map == NULL)
vb@95
   283
        goto enomem;
vb@95
   284
vb@95
   285
    map->color = src->color;
vb@95
   286
vb@95
   287
    if (src->left) {
vb@95
   288
        map->left = _stringpair_map_dup(src->left, map);
vb@95
   289
        if (map->left == NULL)
vb@95
   290
            goto enomem;
vb@95
   291
    }
vb@95
   292
vb@95
   293
    if (src->right) {
vb@95
   294
        map->right = _stringpair_map_dup(src->right, map);
vb@95
   295
        if (map->right == NULL)
vb@95
   296
            goto enomem;
vb@95
   297
    }
vb@95
   298
vb@95
   299
    map->parent_ref = parent;
vb@95
   300
vb@95
   301
    return map;
vb@95
   302
vb@95
   303
enomem:
vb@95
   304
    free_stringpair_map(map);
vb@95
   305
    return NULL;
vb@95
   306
}
vb@95
   307
vb@95
   308
DYNAMIC_API stringpair_map_t * stringpair_map_dup(const stringpair_map_t *src)
vb@95
   309
{
vb@95
   310
    return _stringpair_map_dup(src, NULL);
vb@95
   311
}
vb@95
   312
vb@95
   313
DYNAMIC_API stringpair_map_t * stringpair_map_find(
vb@95
   314
        stringpair_map_t *map,
vb@95
   315
        const char *key
vb@95
   316
    )
vb@95
   317
{
vb@95
   318
    int c;
vb@95
   319
vb@95
   320
    assert(key);
vb@95
   321
vb@95
   322
    if (map == NULL || map->pair == NULL) // empty map
vb@95
   323
        return NULL;
vb@95
   324
vb@97
   325
    c = strcoll(map->pair->key, key);
vb@95
   326
vb@95
   327
    if (c == 0)
vb@95
   328
        return map;
vb@95
   329
    else if (c < 0)
vb@95
   330
        return stringpair_map_find(map->left, key);
vb@95
   331
    else
vb@95
   332
        return stringpair_map_find(map->right, key);
vb@95
   333
}
vb@95
   334
vb@95
   335
static stringpair_map_t * stringpair_map_grandparent(stringpair_map_t *node)
vb@95
   336
{
vb@95
   337
    assert(node);
vb@95
   338
vb@95
   339
    if (node->parent_ref == NULL)
vb@95
   340
        return NULL;
vb@95
   341
vb@95
   342
    return node->parent_ref->parent_ref;
vb@95
   343
}
vb@95
   344
vb@95
   345
static stringpair_map_t * stringpair_map_uncle(stringpair_map_t *node)
vb@95
   346
{
vb@95
   347
    assert(stringpair_map_grandparent(node));
vb@95
   348
vb@95
   349
    if (node->parent_ref == stringpair_map_grandparent(node)->left)
vb@95
   350
        return stringpair_map_grandparent(node)->right;
vb@95
   351
    else
vb@95
   352
        return stringpair_map_grandparent(node)->left;
vb@95
   353
}
vb@95
   354
vb@95
   355
static stringpair_map_t * _stringpair_map_add(
vb@95
   356
        stringpair_map_t *map,
vb@95
   357
        stringpair_t * pair
vb@95
   358
    )
vb@95
   359
{
vb@95
   360
    int c;
vb@95
   361
vb@95
   362
    assert(map);
vb@95
   363
    assert(pair);
vb@95
   364
vb@95
   365
    if (map->pair == NULL) {
vb@95
   366
        map->pair = stringpair_dup(pair);
vb@95
   367
        if (map->pair == NULL)
vb@95
   368
            return NULL;
vb@95
   369
        return map;
vb@95
   370
    }
vb@95
   371
vb@95
   372
    assert(map->pair->key);
vb@95
   373
    assert(pair->key);
vb@95
   374
vb@97
   375
    c = strcoll(map->pair->key, pair->key);
vb@95
   376
    if (c == 0) {
vb@95
   377
        free(map->pair->value);
vb@95
   378
vb@95
   379
        assert(pair->value);
vb@95
   380
vb@95
   381
        map->pair->value = strdup(pair->value);
vb@95
   382
        assert(map->pair->value);
vb@95
   383
        if (map->pair->value == NULL)
vb@95
   384
            return NULL;
vb@95
   385
    }
vb@95
   386
    else if (c < 0) {
vb@95
   387
        if (map->left == NULL) {
vb@95
   388
            map->left = new_stringpair_map(pair);
vb@95
   389
            if (map->left)
vb@95
   390
                return NULL;
vb@95
   391
            map = map->left;
vb@95
   392
        }
vb@95
   393
        else {
vb@95
   394
            map = _stringpair_map_add(map->left, pair);
vb@95
   395
        }
vb@95
   396
    }
vb@95
   397
    else {
vb@95
   398
        if (map->right == NULL) {
vb@95
   399
            map->right = new_stringpair_map(pair);
vb@95
   400
            if (map->right)
vb@95
   401
                return NULL;
vb@95
   402
            map = map->right;
vb@95
   403
        }
vb@95
   404
        else {
vb@95
   405
            map = _stringpair_map_add(map->right, pair);
vb@95
   406
        }
vb@95
   407
    }
vb@95
   408
vb@95
   409
    return map;
vb@95
   410
}
vb@95
   411
vb@95
   412
static void stringpair_map_rotate_left(stringpair_map_t *l)
vb@95
   413
{
vb@95
   414
    stringpair_map_t * _parent;
vb@95
   415
    stringpair_map_t * _r;
vb@95
   416
vb@95
   417
    assert(l);
vb@95
   418
    assert(l->parent_ref);
vb@95
   419
    assert(l->right);
vb@95
   420
vb@95
   421
    _parent = l->parent_ref;
vb@95
   422
    _r = l->right;
vb@95
   423
vb@95
   424
    l->right = _r->left;
vb@95
   425
    _r->left = l;
vb@95
   426
vb@95
   427
    if (_parent->left == l)
vb@95
   428
        _parent->left = _r;
vb@95
   429
    else
vb@95
   430
        _parent->right = _r;
vb@95
   431
}
vb@95
   432
vb@95
   433
static void stringpair_map_rotate_right(stringpair_map_t *r)
vb@95
   434
{
vb@95
   435
    stringpair_map_t * _parent;
vb@95
   436
    stringpair_map_t * _l;
vb@95
   437
vb@95
   438
    assert(r);
vb@95
   439
    assert(r->parent_ref);
vb@95
   440
    assert(r->left);
vb@95
   441
vb@95
   442
    _parent = r->parent_ref;
vb@95
   443
    _l = r->left;
vb@95
   444
vb@95
   445
    r->left = _l->right;
vb@95
   446
    _l->right = r;
vb@95
   447
vb@95
   448
    if (_parent->left == r)
vb@95
   449
        _parent->left = _l;
vb@95
   450
    else
vb@95
   451
        _parent->right = _l;
vb@95
   452
}
vb@95
   453
vb@95
   454
static void stringpair_map_case5(stringpair_map_t *map)
vb@95
   455
{
vb@95
   456
    map->parent_ref->color = rbt_black;
vb@95
   457
    stringpair_map_grandparent(map)->color = rbt_red;
vb@97
   458
vb@95
   459
    if (map == map->parent_ref->left &&
vb@95
   460
            map->parent_ref == stringpair_map_grandparent(map)->left) {
vb@95
   461
        stringpair_map_rotate_right(stringpair_map_grandparent(map));
vb@95
   462
    }
vb@95
   463
    else {
vb@95
   464
        assert(map == map->parent_ref->right &&
vb@95
   465
                map->parent_ref == stringpair_map_grandparent(map)->right);
vb@95
   466
        stringpair_map_rotate_left(stringpair_map_grandparent(map));
vb@95
   467
    }
vb@95
   468
}
vb@95
   469
vb@95
   470
static void stringpair_map_case4(stringpair_map_t *map)
vb@95
   471
{
vb@95
   472
    if (map == map->parent_ref->right &&
vb@95
   473
            map->parent_ref == stringpair_map_grandparent(map)->left) {
vb@95
   474
        stringpair_map_rotate_left(map->parent_ref);
vb@95
   475
        map = map->left;
vb@95
   476
    }
vb@95
   477
    else if (map == map->parent_ref->left &&
vb@95
   478
            map->parent_ref == stringpair_map_grandparent(map)->right) {
vb@95
   479
        stringpair_map_rotate_right(map->parent_ref);
vb@95
   480
        map = map->right;
vb@95
   481
    }
vb@95
   482
vb@95
   483
    stringpair_map_case5(map);
vb@95
   484
}
vb@95
   485
vb@95
   486
static void stringpair_map_case1(stringpair_map_t *map);
vb@95
   487
vb@95
   488
static void stringpair_map_case3(stringpair_map_t *map)
vb@95
   489
{
vb@95
   490
    if (stringpair_map_uncle(map) != NULL &&
vb@95
   491
            stringpair_map_uncle(map)->color == rbt_red) {
vb@95
   492
        map->parent_ref->color = rbt_black;
vb@95
   493
        stringpair_map_uncle(map)->color = rbt_black;
vb@95
   494
        stringpair_map_grandparent(map)->color = rbt_red;
vb@95
   495
vb@95
   496
        stringpair_map_case1(stringpair_map_grandparent(map));
vb@95
   497
    }
vb@95
   498
    else {
vb@95
   499
        stringpair_map_case4(map);
vb@95
   500
    }
vb@95
   501
}
vb@95
   502
vb@95
   503
static void stringpair_map_case2(stringpair_map_t *map)
vb@95
   504
{
vb@95
   505
    if (map->parent_ref->color == rbt_black)
vb@95
   506
        return;
vb@95
   507
    else
vb@95
   508
        stringpair_map_case3(map);
vb@95
   509
}
vb@95
   510
vb@95
   511
static void stringpair_map_case1(stringpair_map_t *map)
vb@95
   512
{
vb@95
   513
    assert(map);
vb@95
   514
vb@95
   515
    if (map->parent_ref == NULL)
vb@95
   516
        map->color = rbt_black;
vb@95
   517
    else
vb@95
   518
        stringpair_map_case2(map);
vb@95
   519
}
vb@95
   520
vb@95
   521
static void stringpair_map_repair(stringpair_map_t *map)
vb@95
   522
{
vb@95
   523
    stringpair_map_case1(map);
vb@95
   524
}
vb@95
   525
vb@95
   526
DYNAMIC_API stringpair_map_t * stringpair_map_add(
vb@95
   527
        stringpair_map_t *map,
vb@95
   528
        stringpair_t * pair
vb@95
   529
    )
vb@95
   530
{
vb@95
   531
    stringpair_map_t * _map = NULL;
vb@95
   532
vb@95
   533
    assert(map);
vb@95
   534
    assert(pair);
vb@95
   535
vb@95
   536
    _map = _stringpair_map_add(map, pair);
vb@95
   537
    if (_map == NULL)
vb@95
   538
        return NULL;
vb@95
   539
vb@95
   540
    stringpair_map_repair(_map);
vb@95
   541
vb@95
   542
    return _map;
vb@95
   543
}
vb@95
   544
vb@48
   545
DYNAMIC_API message *new_message(
vb@38
   546
        PEP_msg_direction dir,
vb@39
   547
        pEp_identity *from,
vb@39
   548
        identity_list *to,
vb@29
   549
        const char *shortmsg
vb@29
   550
    )
vb@29
   551
{
vb@29
   552
    message *msg = calloc(1, sizeof(message));
vb@29
   553
    assert(msg);
vb@29
   554
    if (msg == NULL)
vb@29
   555
        return NULL;
vb@29
   556
vb@39
   557
    if (shortmsg) {
vb@37
   558
        msg->shortmsg = strdup(shortmsg);
vb@37
   559
        assert(msg->shortmsg);
vb@37
   560
        if (msg->shortmsg == NULL) {
vb@37
   561
            free(msg);
vb@37
   562
            return NULL;
vb@37
   563
        }
vb@29
   564
    }
vb@29
   565
vb@29
   566
    msg->dir = dir;
vb@39
   567
    msg->from = from;
vb@39
   568
    msg->to = to;
vb@29
   569
vb@97
   570
    stringpair_t version;
vb@97
   571
    version.key = "X-pEp-Version";
vb@97
   572
    version.value = PEP_VERSION;
vb@97
   573
vb@97
   574
    msg->opt_fields = new_stringpair_map(&version);
vb@97
   575
    if (msg->opt_fields == NULL) {
vb@97
   576
        free_message(msg);
vb@97
   577
        return NULL;
vb@97
   578
    }
vb@97
   579
vb@29
   580
    return msg;
vb@29
   581
}
vb@29
   582
vb@48
   583
DYNAMIC_API void free_message(message *msg)
vb@29
   584
{
vb@63
   585
    if (msg) {
vb@63
   586
        free(msg->id);
vb@63
   587
        free(msg->shortmsg);
vb@63
   588
        free(msg->longmsg);
vb@63
   589
        free(msg->longmsg_formatted);
vb@63
   590
        free_bloblist(msg->attachments);
vb@89
   591
        free(msg->sent);
vb@89
   592
        free(msg->recv);
vb@63
   593
        free_identity(msg->from);
vb@63
   594
        free_identity_list(msg->to);
vb@63
   595
        free_identity(msg->recv_by);
vb@63
   596
        free_identity_list(msg->cc);
vb@63
   597
        free_identity_list(msg->bcc);
vb@94
   598
        free_identity_list(msg->reply_to);
vb@94
   599
        free_stringlist(msg->in_reply_to);
vb@89
   600
        free_stringlist(msg->references);
vb@89
   601
        free_stringlist(msg->keywords);
vb@89
   602
        free(msg->comments);
vb@96
   603
        free_stringpair_map(msg->opt_fields);
vb@63
   604
        free(msg);
vb@63
   605
    }
vb@29
   606
}
vb@29
   607
vb@81
   608
DYNAMIC_API message * message_dup(const message *src)
vb@81
   609
{
vb@81
   610
    message * msg = NULL;
vb@81
   611
    pEp_identity * from = NULL;
vb@81
   612
    identity_list * to = NULL;
vb@81
   613
vb@81
   614
    assert(src);
vb@81
   615
vb@81
   616
    from = identity_dup(src->from);
vb@81
   617
    if (from == NULL)
vb@81
   618
        goto enomem;
vb@81
   619
vb@81
   620
    to = identity_list_dup(src->to);
vb@81
   621
    if (to == NULL)
vb@81
   622
        goto enomem;
vb@81
   623
vb@81
   624
    msg = new_message(src->dir, from, to, src->shortmsg);
vb@81
   625
    if (msg == NULL)
vb@81
   626
        goto enomem;
vb@81
   627
vb@81
   628
    if (src->id) {
vb@81
   629
        msg->id = strdup(src->id);
vb@81
   630
        assert(msg->id);
vb@81
   631
        if (msg->id == NULL)
vb@81
   632
            goto enomem;
vb@81
   633
    }
vb@81
   634
vb@81
   635
    if (src->longmsg) {
vb@81
   636
        msg->longmsg = strdup(src->longmsg);
vb@81
   637
        assert(msg->longmsg);
vb@81
   638
        if (msg->longmsg == NULL)
vb@81
   639
            goto enomem;
vb@81
   640
    }
vb@81
   641
    
vb@81
   642
    if (src->longmsg_formatted) {
vb@81
   643
        msg->longmsg_formatted = strdup(src->longmsg_formatted);
vb@81
   644
        assert(msg->longmsg_formatted);
vb@81
   645
        if (msg->longmsg_formatted == NULL)
vb@81
   646
            goto enomem;
vb@81
   647
    }
vb@81
   648
vb@81
   649
    if (src->attachments) {
vb@81
   650
        msg->attachments = bloblist_dup(src->attachments);
vb@81
   651
        if (msg->attachments == NULL)
vb@81
   652
            goto enomem;
vb@81
   653
    }
vb@81
   654
vb@81
   655
    msg->rawmsg_ref = src->rawmsg_ref;
vb@81
   656
    msg->rawmsg_size = src->rawmsg_size;
vb@89
   657
vb@89
   658
    if (src->sent) {
vb@89
   659
        msg->sent = malloc(sizeof(timestamp));
vb@89
   660
        if (msg->sent == NULL)
vb@89
   661
            goto enomem;
vb@89
   662
        memcpy(msg->sent, src->sent, sizeof(timestamp));
vb@89
   663
    }
vb@89
   664
vb@89
   665
    if (src->recv) {
vb@89
   666
        msg->recv = malloc(sizeof(timestamp));
vb@89
   667
        if (msg->recv == NULL)
vb@89
   668
            goto enomem;
vb@89
   669
        memcpy(msg->recv, src->recv, sizeof(timestamp));
vb@89
   670
    }
vb@81
   671
vb@81
   672
    if (src->recv_by) {
vb@81
   673
        msg->recv_by = identity_dup(src->recv_by);
vb@81
   674
        if (msg->recv_by == NULL)
vb@81
   675
            goto enomem;
vb@81
   676
    }
vb@81
   677
vb@81
   678
    if (src->cc) {
vb@81
   679
        msg->cc = identity_list_dup(src->cc);
vb@81
   680
        if (msg->cc == NULL)
vb@81
   681
            goto enomem;
vb@81
   682
    }
vb@81
   683
vb@81
   684
    if (src->bcc) {
vb@81
   685
        msg->bcc = identity_list_dup(src->bcc);
vb@81
   686
        if (msg->bcc == NULL)
vb@81
   687
            goto enomem;
vb@81
   688
    }
vb@81
   689
vb@81
   690
    if (src->reply_to) {
vb@94
   691
        msg->reply_to = identity_list_dup(src->reply_to);
vb@81
   692
        if (msg->reply_to == NULL)
vb@81
   693
            goto enomem;
vb@81
   694
    }
vb@81
   695
vb@89
   696
    if (src->in_reply_to) {
vb@94
   697
        msg->in_reply_to = stringlist_dup(src->in_reply_to);
vb@89
   698
        assert(msg->in_reply_to);
vb@89
   699
        if (msg->in_reply_to == NULL)
vb@81
   700
            goto enomem;
vb@81
   701
    }
vb@81
   702
vb@81
   703
    msg->refering_msg_ref = src->refering_msg_ref;
vb@81
   704
    
vb@89
   705
    if (src->references) {
vb@89
   706
        msg->references = stringlist_dup(src->references);
vb@89
   707
        if (msg->references == NULL)
vb@89
   708
            goto enomem;
vb@89
   709
    }
vb@89
   710
vb@81
   711
    if (src->refered_by) {
vb@81
   712
        msg->refered_by = message_ref_list_dup(src->refered_by);
vb@81
   713
        if (msg->refered_by == NULL)
vb@81
   714
            goto enomem;
vb@81
   715
    }
vb@81
   716
vb@89
   717
    if (src->keywords) {
vb@89
   718
        msg->keywords = stringlist_dup(src->keywords);
vb@89
   719
        if (msg->keywords == NULL)
vb@89
   720
            goto enomem;
vb@89
   721
    }
vb@89
   722
vb@89
   723
    if (src->comments) {
vb@89
   724
        msg->comments = strdup(src->comments);
vb@89
   725
        assert(msg->comments);
vb@89
   726
        if (msg->comments == NULL)
vb@89
   727
            goto enomem;
vb@89
   728
    }
vb@89
   729
vb@96
   730
    if (src->opt_fields) {
vb@96
   731
        msg->opt_fields = stringpair_map_dup(src->opt_fields);
vb@96
   732
        if (msg->opt_fields == NULL)
vb@96
   733
            goto enomem;
vb@96
   734
    }
vb@96
   735
vb@81
   736
    msg->enc_format = src->enc_format;
vb@81
   737
vb@81
   738
    return msg;
vb@81
   739
vb@81
   740
enomem:
vb@81
   741
    if (msg) {
vb@81
   742
        free_message(msg);
vb@81
   743
    }
vb@81
   744
    else {
vb@81
   745
        free_identity(from);
vb@81
   746
        free_identity_list(to);
vb@81
   747
    }
vb@81
   748
vb@81
   749
    return NULL;
vb@81
   750
}
vb@81
   751
vb@48
   752
DYNAMIC_API message_ref_list *new_message_ref_list(message *msg)
vb@29
   753
{
vb@29
   754
    message_ref_list *msg_list = calloc(1, sizeof(message_ref_list));
vb@29
   755
    assert(msg_list);
vb@29
   756
    if (msg_list == NULL)
vb@29
   757
        return NULL;
vb@29
   758
vb@29
   759
    msg_list->msg_ref = msg;
vb@29
   760
vb@29
   761
    return msg_list;
vb@29
   762
}
vb@29
   763
vb@48
   764
DYNAMIC_API void free_message_ref_list(message_ref_list *msg_list)
vb@29
   765
{
vb@29
   766
    if (msg_list) {
vb@29
   767
        free_message_ref_list(msg_list->next);
vb@29
   768
        free(msg_list);
vb@29
   769
    }
vb@29
   770
}
vb@29
   771
vb@81
   772
DYNAMIC_API message_ref_list *message_ref_list_dup(
vb@81
   773
        const message_ref_list *src
vb@81
   774
    )
vb@81
   775
{
vb@81
   776
    message_ref_list * msg_list = NULL;
vb@81
   777
vb@81
   778
    assert(src);
vb@81
   779
vb@81
   780
    msg_list = new_message_ref_list(src->msg_ref);
vb@81
   781
    if (msg_list == NULL)
vb@81
   782
        goto enomem;
vb@81
   783
vb@81
   784
    if (src->next) {
vb@81
   785
        msg_list->next = message_ref_list_dup(src->next);
vb@81
   786
        if (msg_list->next == NULL)
vb@81
   787
            goto enomem;
vb@81
   788
    }
vb@81
   789
vb@81
   790
    return msg_list;
vb@81
   791
vb@81
   792
enomem:
vb@81
   793
    free_message_ref_list(msg_list);
vb@81
   794
    return NULL;
vb@81
   795
}
vb@81
   796
vb@48
   797
DYNAMIC_API message_ref_list *message_ref_list_add(message_ref_list *msg_list, message *msg)
vb@29
   798
{
vb@29
   799
    assert(msg);
vb@29
   800
vb@38
   801
    if (msg_list == NULL)
vb@38
   802
        return new_message_ref_list(msg);
vb@38
   803
vb@29
   804
    if (msg_list->msg_ref == NULL) {
vb@29
   805
        msg_list->msg_ref = msg;
vb@29
   806
        return msg_list;
vb@29
   807
    }
vb@29
   808
    else if (msg_list->next == NULL) {
vb@29
   809
        msg_list->next = new_message_ref_list(msg);
vb@29
   810
        assert(msg_list->next);
vb@29
   811
        return msg_list->next;
vb@29
   812
    }
vb@29
   813
    else {
vb@29
   814
        return message_ref_list_add(msg_list->next, msg);
vb@29
   815
    }
vb@29
   816
}
vb@29
   817