... sync
authorVolker Birk <vb@pep.foundation>
Mon, 13 Aug 2018 16:45:23 +0200
branchsync
changeset 28446fce34991f7d
parent 2843 d3b9b81607d1
child 2845 d474c5ebfec8
...
sync/Makefile
sync/cond_act.yml2
sync/cond_act_sync.yml2
sync/gen_actions.ysl2
sync/gen_codec.ysl2
sync/gen_message_func.ysl2
sync/gen_statemachine.ysl2
sync/sql_func.yml2
     1.1 --- a/sync/Makefile	Mon Aug 13 16:34:36 2018 +0200
     1.2 +++ b/sync/Makefile	Mon Aug 13 16:45:23 2018 +0200
     1.3 @@ -9,7 +9,7 @@
     1.4  	touch .codegen
     1.5  	make copy
     1.6  
     1.7 -.actions: sync.fsm gen_actions.ysl2 fsm.yml2 functions.ysl2 cond_act.yml2
     1.8 +.actions: sync.fsm gen_actions.ysl2 fsm.yml2 functions.ysl2 $(wildcard cond_act_*.yml2)
     1.9  	$(YML2_PROC) -y gen_actions.ysl2 $< -o $@
    1.10  
    1.11  .statemachines: sync.fsm gen_statemachine.ysl2 fsm.yml2 functions.ysl2
     2.1 --- a/sync/cond_act.yml2	Mon Aug 13 16:34:36 2018 +0200
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,285 +0,0 @@
     2.4 -// This file is under GNU General Public License 3.0
     2.5 -// see LICENSE.txt
     2.6 -
     2.7 -// generate conditions and actions
     2.8 -
     2.9 -// Copyleft (c) 2017, p≡p foundation
    2.10 -
    2.11 -// Written by Volker Birk
    2.12 -
    2.13 -
    2.14 -// prepare SQL statement
    2.15 -
    2.16 -function "init_sql" {
    2.17 -    param "sql";
    2.18 -    ||
    2.19 -        static const char *sql = `copy '$sql'`;
    2.20 -        static const size_t len = sizeof(`copy '$sql'`);
    2.21 -        sqlite3_stmt *_sql;
    2.22 -        int int_result = sqlite3_prepare_v2(session->db, sql, (int) len, &_sql, NULL);
    2.23 -        assert(int_result == SQLITE_OK);
    2.24 -        if (!(int_result == SQLITE_OK))
    2.25 -            return PEP_UNKNOWN_ERROR;
    2.26 -
    2.27 -    ||
    2.28 -}
    2.29 -
    2.30 -// exec_sql_* is returning _result
    2.31 -
    2.32 -function "exec_sql_int" {
    2.33 -    param "sql";
    2.34 -    call "init_sql" with "sql", "$sql";
    2.35 -    ||
    2.36 -        int _result = 0;
    2.37 -        int_result = sqlite3_step(_sql);
    2.38 -        assert(int_result == SQLITE_ROW);
    2.39 -        if (int_result == SQLITE_ROW)
    2.40 -            _result = sqlite3_column_int(_sql, 0);
    2.41 -        sqlite3_finalize(_sql);
    2.42 -        if (int_result != SQLITE_ROW)
    2.43 -            return PEP_UNKNOWN_ERROR;
    2.44 -
    2.45 -    ||
    2.46 -}
    2.47 -
    2.48 -// condition: PEP_STATUS «@name»(PEP_SESSION session, bool *result)
    2.49 -
    2.50 -condition deviceGrouped {
    2.51 -    call "exec_sql_int" with "sql"
    2.52 -        > "select count(*) from identity where user_id = '"PEP_OWN_USERID"' and (flags & 4) = 4;"
    2.53 -    |> *result = _result > 0;
    2.54 -}
    2.55 -
    2.56 -condition partnerIsGrouped
    2.57 -|> *result = session->sync_state.keysync.is_group;
    2.58 -
    2.59 -condition challengeAccepted
    2.60 -||
    2.61 -    TID_t *t1 = &session->sync_state.keysync.challenge;
    2.62 -    TID_t *t2 = &session->own_sync_state.challenge;
    2.63 -
    2.64 -    *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
    2.65 -||
    2.66 -
    2.67 -condition keyElectionWon
    2.68 -||
    2.69 -    pEp_identity *from = session->sync_state.common.from;
    2.70 -
    2.71 -    assert(from && from->fpr && from->fpr[0] && from->address && from->address[0]);
    2.72 -    if (!(from && from->fpr && from->fpr[0] && from->address && from->address[0]))
    2.73 -        return PEP_ILLEGAL_VALUE;
    2.74 -
    2.75 -    pEp_identity *me = NULL;
    2.76 -    PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
    2.77 -    assert(status == PEP_STATUS_OK);
    2.78 -    if (status)
    2.79 -        return status;
    2.80 -
    2.81 -    assert(me->fpr && me->fpr[0]);
    2.82 -    if (!(me->fpr && me->fpr[0])) {
    2.83 -        free_identity(me);
    2.84 -        return PEP_ILLEGAL_VALUE;
    2.85 -    }
    2.86 -
    2.87 -    size_t len = MIN(strlen(from->fpr), strlen(me->fpr));
    2.88 -    *result = strncasecmp(from->fpr, me->fpr, len) > 0;
    2.89 -    free_identity(me);
    2.90 -||
    2.91 -
    2.92 -// action: PEP_STATUS «@name»(PEP_SESSION session)
    2.93 -
    2.94 -action closeHandshakeDialog
    2.95 -||
    2.96 -    assert(session->notifyHandshake);
    2.97 -    if (!session->notifyHandshake)
    2.98 -        return PEP_SYNC_NO_NOTIFY_CALLBACK;
    2.99 -
   2.100 -    PEP_STATUS status = session->notifyHandshake(
   2.101 -            session->sync_management, NULL, NULL, SYNC_NOTIFY_OVERTAKEN);
   2.102 -    if (status)
   2.103 -        return status;
   2.104 -||
   2.105 -
   2.106 -function "new_UUID" {
   2.107 -    param "dst";
   2.108 -    ||
   2.109 -        pEpUUID c;
   2.110 -        uuid_generate_random(c);
   2.111 -
   2.112 -        OCTET_STRING_fromBuf(«$dst», (char *) c, 16);
   2.113 -    ||
   2.114 -}
   2.115 -
   2.116 -function "copy_UUID" {
   2.117 -    param "src", param "dst";
   2.118 -    ||
   2.119 -        TID_t *src = «$src»;
   2.120 -        TID_t *dst = «$dst»;
   2.121 -
   2.122 -        assert(src->size == 16);
   2.123 -        if (!(src->size == 16))
   2.124 -            return PEP_UNKNOWN_ERROR;
   2.125 -
   2.126 -        OCTET_STRING_fromBuf(dst, (char *) src->buf, src->size);
   2.127 -    ||
   2.128 -}
   2.129 -
   2.130 -action openChallenge
   2.131 -    call "new_UUID" with "dst" > &session->own_sync_state.challenge
   2.132 -
   2.133 -action storeChallenge call "copy_UUID" {
   2.134 -    with "src" > &session->sync_state.keysync.challenge
   2.135 -    with "dst" > &session->own_sync_state.challenge
   2.136 -}
   2.137 -
   2.138 -action openTransaction
   2.139 -    call "new_UUID" with "dst" > &session->own_sync_state.transaction
   2.140 -
   2.141 -action storeTransaction call "copy_UUID" {
   2.142 -    with "src" > &session->sync_state.keysync.transaction
   2.143 -    with "dst" >  &session->own_sync_state.transaction
   2.144 -}
   2.145 -
   2.146 -function "show_handshake" {
   2.147 -    param "type";
   2.148 -    ||
   2.149 -        assert(session->notifyHandshake);
   2.150 -        if (!session->notifyHandshake)
   2.151 -            return PEP_SYNC_NO_NOTIFY_CALLBACK;
   2.152 -     
   2.153 -        assert(session->sync_state.common.from);
   2.154 -        if (!session->sync_state.common.from)
   2.155 -            return PEP_ILLEGAL_VALUE;
   2.156 -
   2.157 -        pEp_identity *from = session->sync_state.common.from;
   2.158 -        pEp_identity *me = NULL;
   2.159 -        PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
   2.160 -        assert(status == PEP_STATUS_OK);
   2.161 -        if (status)
   2.162 -            return status;
   2.163 -
   2.164 -        assert(me->fpr && me->fpr[0]);
   2.165 -        if (!(me->fpr && me->fpr[0])) {
   2.166 -            free_identity(me);
   2.167 -            return PEP_ILLEGAL_VALUE;
   2.168 -        }
   2.169 -
   2.170 -        pEp_identity *partner = identity_dup(from);
   2.171 -        if (!partner) {
   2.172 -            free_identity(me);
   2.173 -            return PEP_OUT_OF_MEMORY;
   2.174 -        }
   2.175 -
   2.176 -        status = session->notifyHandshake(session->sync_management, me,
   2.177 -                partner, «$type»);
   2.178 -        if (status)
   2.179 -            return status;
   2.180 -    ||
   2.181 -}
   2.182 -
   2.183 -action showSoleHandshake
   2.184 -    call "show_handshake" with "type" > SYNC_NOTIFY_INIT_FORM_GROUP
   2.185 -
   2.186 -action showJoinGroupHandshake
   2.187 -    call "show_handshake" with "type" > SYNC_NOTIFY_INIT_ADD_OUR_DEVICE
   2.188 -
   2.189 -action showGroupedHandshake
   2.190 -    call "show_handshake" with "type" > SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE
   2.191 -
   2.192 -action saveGroupKeys
   2.193 -||
   2.194 -    identity_list *il = IdentityList_to_identity_list(&session->sync_state.keysync.identities, NULL);
   2.195 -    if (!il)
   2.196 -        return PEP_OUT_OF_MEMORY;
   2.197 -    
   2.198 -    // BUG: this should be a transaction and been rolled back completely on error
   2.199 -    for (identity_list *_il = il; _il && _il->ident; _il = _il->next) {
   2.200 -        PEP_STATUS status = set_identity(session, _il->ident);
   2.201 -        if (status) {
   2.202 -            free_identity_list(il);
   2.203 -            return status;
   2.204 -        }
   2.205 -    }
   2.206 -
   2.207 -    free_identity_list(il);
   2.208 -||
   2.209 -
   2.210 -action ownKeysAreGroupKeys {
   2.211 -    call "init_sql" with "sql" {
   2.212 -        ||
   2.213 -        "select fpr, username, comm_type, lang,"
   2.214 -                "   identity.flags | pgp_keypair.flags"
   2.215 -                "   from identity"
   2.216 -                "   join person on id = identity.user_id"
   2.217 -                "   join pgp_keypair on fpr = identity.main_key_id"
   2.218 -                "   join trust on id = trust.user_id"
   2.219 -                "       and pgp_keypair_fpr = identity.main_key_id"
   2.220 -        ||
   2.221 -        >         "   where identity.user_id = '" PEP_OWN_USERID "';"
   2.222 -    }
   2.223 -
   2.224 -    ||
   2.225 -        identity_list *il = new_identity_list(NULL);
   2.226 -        if (!il)
   2.227 -            return PEP_OUT_OF_MEMORY;
   2.228 -
   2.229 -        pEp_identity *from = session->sync_state.common.from;
   2.230 -        identity_list *_il = il;
   2.231 -
   2.232 -        int result;
   2.233 -        do {
   2.234 -            result = sqlite3_step(_sql);
   2.235 -            pEp_identity *_identity = NULL;
   2.236 -            switch (result) {
   2.237 -            case SQLITE_ROW:
   2.238 -                _identity = new_identity(
   2.239 -                        from->address,
   2.240 -                        (const char *) sqlite3_column_text(_sql, 0),
   2.241 -                        from->user_id,
   2.242 -                        (const char *) sqlite3_column_text(_sql, 1)
   2.243 -                        );
   2.244 -                assert(_identity);
   2.245 -                if (_identity == NULL)
   2.246 -                    return PEP_OUT_OF_MEMORY;
   2.247 -
   2.248 -                _identity->comm_type = (PEP_comm_type)
   2.249 -                    sqlite3_column_int(_sql, 2);
   2.250 -                const char* const _lang = (const char *)
   2.251 -                    sqlite3_column_text(_sql, 3);
   2.252 -                if (_lang && _lang[0]) {
   2.253 -                    assert(_lang[0] >= 'a' && _lang[0] <= 'z');
   2.254 -                    assert(_lang[1] >= 'a' && _lang[1] <= 'z');
   2.255 -                    assert(_lang[2] == 0);
   2.256 -                    _identity->lang[0] = _lang[0];
   2.257 -                    _identity->lang[1] = _lang[1];
   2.258 -                    _identity->lang[2] = 0;
   2.259 -                }
   2.260 -                _identity->flags = (unsigned int)
   2.261 -                    sqlite3_column_int(_sql, 4);
   2.262 -
   2.263 -                _il = identity_list_add(_il, _identity);
   2.264 -                if (!_il) {
   2.265 -                    free_identity_list(il);
   2.266 -                    free_identity(_identity);
   2.267 -                    return PEP_OUT_OF_MEMORY;
   2.268 -                }
   2.269 -                break;
   2.270 -
   2.271 -            case SQLITE_DONE:
   2.272 -                break;
   2.273 -
   2.274 -            default:
   2.275 -                free_identity_list(il);
   2.276 -                return PEP_UNKNOWN_ERROR;
   2.277 -            }
   2.278 -        } while (result != SQLITE_DONE);
   2.279 -
   2.280 -        IdentityList_t *r = IdentityList_from_identity_list(il, &session->sync_state.keysync.identities);
   2.281 -        free_identity_list(il);
   2.282 -        if (!r)
   2.283 -            return PEP_OUT_OF_MEMORY;
   2.284 -    ||
   2.285 -}
   2.286 -
   2.287 -action disable;
   2.288 -
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/sync/cond_act_sync.yml2	Mon Aug 13 16:45:23 2018 +0200
     3.3 @@ -0,0 +1,253 @@
     3.4 +// This file is under GNU General Public License 3.0
     3.5 +// see LICENSE.txt
     3.6 +
     3.7 +// generate conditions and actions
     3.8 +
     3.9 +// Copyleft (c) 2017, p≡p foundation
    3.10 +
    3.11 +// Written by Volker Birk
    3.12 +
    3.13 +
    3.14 +include ./sql_func.yml2
    3.15 +
    3.16 +// condition: PEP_STATUS «@name»(PEP_SESSION session, bool *result)
    3.17 +
    3.18 +condition deviceGrouped {
    3.19 +    call "exec_sql_int" with "sql"
    3.20 +        > "select count(*) from identity where user_id = '"PEP_OWN_USERID"' and (flags & 4) = 4;"
    3.21 +    |> *result = _result > 0;
    3.22 +}
    3.23 +
    3.24 +condition partnerIsGrouped
    3.25 +|> *result = session->sync_state.keysync.is_group;
    3.26 +
    3.27 +condition challengeAccepted
    3.28 +||
    3.29 +    TID_t *t1 = &session->sync_state.keysync.challenge;
    3.30 +    TID_t *t2 = &session->own_sync_state.challenge;
    3.31 +
    3.32 +    *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
    3.33 +||
    3.34 +
    3.35 +condition keyElectionWon
    3.36 +||
    3.37 +    pEp_identity *from = session->sync_state.common.from;
    3.38 +
    3.39 +    assert(from && from->fpr && from->fpr[0] && from->address && from->address[0]);
    3.40 +    if (!(from && from->fpr && from->fpr[0] && from->address && from->address[0]))
    3.41 +        return PEP_ILLEGAL_VALUE;
    3.42 +
    3.43 +    pEp_identity *me = NULL;
    3.44 +    PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
    3.45 +    assert(status == PEP_STATUS_OK);
    3.46 +    if (status)
    3.47 +        return status;
    3.48 +
    3.49 +    assert(me->fpr && me->fpr[0]);
    3.50 +    if (!(me->fpr && me->fpr[0])) {
    3.51 +        free_identity(me);
    3.52 +        return PEP_ILLEGAL_VALUE;
    3.53 +    }
    3.54 +
    3.55 +    size_t len = MIN(strlen(from->fpr), strlen(me->fpr));
    3.56 +    *result = strncasecmp(from->fpr, me->fpr, len) > 0;
    3.57 +    free_identity(me);
    3.58 +||
    3.59 +
    3.60 +// action: PEP_STATUS «@name»(PEP_SESSION session)
    3.61 +
    3.62 +action closeHandshakeDialog
    3.63 +||
    3.64 +    assert(session->notifyHandshake);
    3.65 +    if (!session->notifyHandshake)
    3.66 +        return PEP_SYNC_NO_NOTIFY_CALLBACK;
    3.67 +
    3.68 +    PEP_STATUS status = session->notifyHandshake(
    3.69 +            session->sync_management, NULL, NULL, SYNC_NOTIFY_OVERTAKEN);
    3.70 +    if (status)
    3.71 +        return status;
    3.72 +||
    3.73 +
    3.74 +function "new_UUID" {
    3.75 +    param "dst";
    3.76 +    ||
    3.77 +        pEpUUID c;
    3.78 +        uuid_generate_random(c);
    3.79 +
    3.80 +        OCTET_STRING_fromBuf(«$dst», (char *) c, 16);
    3.81 +    ||
    3.82 +}
    3.83 +
    3.84 +function "copy_UUID" {
    3.85 +    param "src", param "dst";
    3.86 +    ||
    3.87 +        TID_t *src = «$src»;
    3.88 +        TID_t *dst = «$dst»;
    3.89 +
    3.90 +        assert(src->size == 16);
    3.91 +        if (!(src->size == 16))
    3.92 +            return PEP_UNKNOWN_ERROR;
    3.93 +
    3.94 +        OCTET_STRING_fromBuf(dst, (char *) src->buf, src->size);
    3.95 +    ||
    3.96 +}
    3.97 +
    3.98 +action openChallenge
    3.99 +    call "new_UUID" with "dst" > &session->own_sync_state.challenge
   3.100 +
   3.101 +action storeChallenge call "copy_UUID" {
   3.102 +    with "src" > &session->sync_state.keysync.challenge
   3.103 +    with "dst" > &session->own_sync_state.challenge
   3.104 +}
   3.105 +
   3.106 +action openTransaction
   3.107 +    call "new_UUID" with "dst" > &session->own_sync_state.transaction
   3.108 +
   3.109 +action storeTransaction call "copy_UUID" {
   3.110 +    with "src" > &session->sync_state.keysync.transaction
   3.111 +    with "dst" >  &session->own_sync_state.transaction
   3.112 +}
   3.113 +
   3.114 +function "show_handshake" {
   3.115 +    param "type";
   3.116 +    ||
   3.117 +        assert(session->notifyHandshake);
   3.118 +        if (!session->notifyHandshake)
   3.119 +            return PEP_SYNC_NO_NOTIFY_CALLBACK;
   3.120 +     
   3.121 +        assert(session->sync_state.common.from);
   3.122 +        if (!session->sync_state.common.from)
   3.123 +            return PEP_ILLEGAL_VALUE;
   3.124 +
   3.125 +        pEp_identity *from = session->sync_state.common.from;
   3.126 +        pEp_identity *me = NULL;
   3.127 +        PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
   3.128 +        assert(status == PEP_STATUS_OK);
   3.129 +        if (status)
   3.130 +            return status;
   3.131 +
   3.132 +        assert(me->fpr && me->fpr[0]);
   3.133 +        if (!(me->fpr && me->fpr[0])) {
   3.134 +            free_identity(me);
   3.135 +            return PEP_ILLEGAL_VALUE;
   3.136 +        }
   3.137 +
   3.138 +        pEp_identity *partner = identity_dup(from);
   3.139 +        if (!partner) {
   3.140 +            free_identity(me);
   3.141 +            return PEP_OUT_OF_MEMORY;
   3.142 +        }
   3.143 +
   3.144 +        status = session->notifyHandshake(session->sync_management, me,
   3.145 +                partner, «$type»);
   3.146 +        if (status)
   3.147 +            return status;
   3.148 +    ||
   3.149 +}
   3.150 +
   3.151 +action showSoleHandshake
   3.152 +    call "show_handshake" with "type" > SYNC_NOTIFY_INIT_FORM_GROUP
   3.153 +
   3.154 +action showJoinGroupHandshake
   3.155 +    call "show_handshake" with "type" > SYNC_NOTIFY_INIT_ADD_OUR_DEVICE
   3.156 +
   3.157 +action showGroupedHandshake
   3.158 +    call "show_handshake" with "type" > SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE
   3.159 +
   3.160 +action saveGroupKeys
   3.161 +||
   3.162 +    identity_list *il = IdentityList_to_identity_list(&session->sync_state.keysync.identities, NULL);
   3.163 +    if (!il)
   3.164 +        return PEP_OUT_OF_MEMORY;
   3.165 +    
   3.166 +    // BUG: this should be a transaction and been rolled back completely on error
   3.167 +    for (identity_list *_il = il; _il && _il->ident; _il = _il->next) {
   3.168 +        PEP_STATUS status = set_identity(session, _il->ident);
   3.169 +        if (status) {
   3.170 +            free_identity_list(il);
   3.171 +            return status;
   3.172 +        }
   3.173 +    }
   3.174 +
   3.175 +    free_identity_list(il);
   3.176 +||
   3.177 +
   3.178 +action ownKeysAreGroupKeys {
   3.179 +    call "init_sql" with "sql" {
   3.180 +        ||
   3.181 +        "select fpr, username, comm_type, lang,"
   3.182 +                "   identity.flags | pgp_keypair.flags"
   3.183 +                "   from identity"
   3.184 +                "   join person on id = identity.user_id"
   3.185 +                "   join pgp_keypair on fpr = identity.main_key_id"
   3.186 +                "   join trust on id = trust.user_id"
   3.187 +                "       and pgp_keypair_fpr = identity.main_key_id"
   3.188 +        ||
   3.189 +        >         "   where identity.user_id = '" PEP_OWN_USERID "';"
   3.190 +    }
   3.191 +
   3.192 +    ||
   3.193 +        identity_list *il = new_identity_list(NULL);
   3.194 +        if (!il)
   3.195 +            return PEP_OUT_OF_MEMORY;
   3.196 +
   3.197 +        pEp_identity *from = session->sync_state.common.from;
   3.198 +        identity_list *_il = il;
   3.199 +
   3.200 +        int result;
   3.201 +        do {
   3.202 +            result = sqlite3_step(_sql);
   3.203 +            pEp_identity *_identity = NULL;
   3.204 +            switch (result) {
   3.205 +            case SQLITE_ROW:
   3.206 +                _identity = new_identity(
   3.207 +                        from->address,
   3.208 +                        (const char *) sqlite3_column_text(_sql, 0),
   3.209 +                        from->user_id,
   3.210 +                        (const char *) sqlite3_column_text(_sql, 1)
   3.211 +                        );
   3.212 +                assert(_identity);
   3.213 +                if (_identity == NULL)
   3.214 +                    return PEP_OUT_OF_MEMORY;
   3.215 +
   3.216 +                _identity->comm_type = (PEP_comm_type)
   3.217 +                    sqlite3_column_int(_sql, 2);
   3.218 +                const char* const _lang = (const char *)
   3.219 +                    sqlite3_column_text(_sql, 3);
   3.220 +                if (_lang && _lang[0]) {
   3.221 +                    assert(_lang[0] >= 'a' && _lang[0] <= 'z');
   3.222 +                    assert(_lang[1] >= 'a' && _lang[1] <= 'z');
   3.223 +                    assert(_lang[2] == 0);
   3.224 +                    _identity->lang[0] = _lang[0];
   3.225 +                    _identity->lang[1] = _lang[1];
   3.226 +                    _identity->lang[2] = 0;
   3.227 +                }
   3.228 +                _identity->flags = (unsigned int)
   3.229 +                    sqlite3_column_int(_sql, 4);
   3.230 +
   3.231 +                _il = identity_list_add(_il, _identity);
   3.232 +                if (!_il) {
   3.233 +                    free_identity_list(il);
   3.234 +                    free_identity(_identity);
   3.235 +                    return PEP_OUT_OF_MEMORY;
   3.236 +                }
   3.237 +                break;
   3.238 +
   3.239 +            case SQLITE_DONE:
   3.240 +                break;
   3.241 +
   3.242 +            default:
   3.243 +                free_identity_list(il);
   3.244 +                return PEP_UNKNOWN_ERROR;
   3.245 +            }
   3.246 +        } while (result != SQLITE_DONE);
   3.247 +
   3.248 +        IdentityList_t *r = IdentityList_from_identity_list(il, &session->sync_state.keysync.identities);
   3.249 +        free_identity_list(il);
   3.250 +        if (!r)
   3.251 +            return PEP_OUT_OF_MEMORY;
   3.252 +    ||
   3.253 +}
   3.254 +
   3.255 +action disable;
   3.256 +
     4.1 --- a/sync/gen_actions.ysl2	Mon Aug 13 16:34:36 2018 +0200
     4.2 +++ b/sync/gen_actions.ysl2	Mon Aug 13 16:45:23 2018 +0200
     4.3 @@ -21,7 +21,7 @@
     4.4      include standardlib.ysl2
     4.5      include ./functions.ysl2
     4.6  
     4.7 -    include ./cond_act.yml2
     4.8 +    include ./cond_act_*.yml2
     4.9  
    4.10      template "/protocol" {
    4.11          document "generated/{@name}_actions.c", "text" {
     5.1 --- a/sync/gen_codec.ysl2	Mon Aug 13 16:34:36 2018 +0200
     5.2 +++ b/sync/gen_codec.ysl2	Mon Aug 13 16:45:23 2018 +0200
     5.3 @@ -119,7 +119,7 @@
     5.4              *msg = NULL;
     5.5              uper_decode_complete(NULL, &asn_DEF_«@name», (void **) &msg, data, size);
     5.6              if (!msg)
     5.7 -                return PEP_SYNC_ILLEGAL_MESSAGE;
     5.8 +                return PEP_«yml:ucase(@name)»_ILLEGAL_MESSAGE;
     5.9  
    5.10              return PEP_STATUS_OK;
    5.11          }
    5.12 @@ -210,7 +210,7 @@
    5.13              asn_dec_rval_t dr = xer_decode(NULL, &asn_DEF_«@name», (void **) &msg,
    5.14                      (const void *) text, strlen(text));
    5.15              if (dr.code != RC_OK) {
    5.16 -                status = PEP_SYNC_ILLEGAL_MESSAGE;
    5.17 +                status = PEP_«yml:ucase(@name)»_ILLEGAL_MESSAGE;
    5.18                  goto the_end;
    5.19              }
    5.20  
     6.1 --- a/sync/gen_message_func.ysl2	Mon Aug 13 16:34:36 2018 +0200
     6.2 +++ b/sync/gen_message_func.ysl2	Mon Aug 13 16:45:23 2018 +0200
     6.3 @@ -105,7 +105,7 @@
     6.4      |> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->own_«yml:lcase(../../../@name)»_state.«@name»);
     6.5  ||
     6.6  
     6.7 -    memset(&session->sync_state, 0, sizeof(session->sync_state));
     6.8 +    memset(&session->«yml:lcase(@name)»_state, 0, sizeof(session->«yml:lcase(@name)»_state));
     6.9  }
    6.10  
    6.11  «@name»_t *new_«@name»_message(«@name»_PR fsm, int message_type)
     7.1 --- a/sync/gen_statemachine.ysl2	Mon Aug 13 16:34:36 2018 +0200
     7.2 +++ b/sync/gen_statemachine.ysl2	Mon Aug 13 16:45:23 2018 +0200
     7.3 @@ -386,13 +386,13 @@
     7.4  
     7.5                  if (ev->fsm) {
     7.6                      if (ev->fsm != fsm |`> |` ev->event != event) {
     7.7 -                        status = PEP_SYNC_ILLEGAL_MESSAGE;
     7.8 +                        status = PEP_«yml:ucase(@name)»_ILLEGAL_MESSAGE;
     7.9                          goto error;
    7.10                      }
    7.11                  }
    7.12                  else {
    7.13                      if (ev->event) {
    7.14 -                        status = PEP_SYNC_ILLEGAL_MESSAGE;
    7.15 +                        status = PEP_«yml:ucase(@name)»_ILLEGAL_MESSAGE;
    7.16                          goto error;
    7.17                      }
    7.18                      ev->fsm = fsm;
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/sync/sql_func.yml2	Mon Aug 13 16:45:23 2018 +0200
     8.3 @@ -0,0 +1,34 @@
     8.4 +// prepare SQL statement
     8.5 +
     8.6 +function "init_sql" {
     8.7 +    param "sql";
     8.8 +    ||
     8.9 +        static const char *sql = `copy '$sql'`;
    8.10 +        static const size_t len = sizeof(`copy '$sql'`);
    8.11 +        sqlite3_stmt *_sql;
    8.12 +        int int_result = sqlite3_prepare_v2(session->db, sql, (int) len, &_sql, NULL);
    8.13 +        assert(int_result == SQLITE_OK);
    8.14 +        if (!(int_result == SQLITE_OK))
    8.15 +            return PEP_UNKNOWN_ERROR;
    8.16 +
    8.17 +    ||
    8.18 +}
    8.19 +
    8.20 +// exec_sql_* is returning _result
    8.21 +
    8.22 +function "exec_sql_int" {
    8.23 +    param "sql";
    8.24 +    call "init_sql" with "sql", "$sql";
    8.25 +    ||
    8.26 +        int _result = 0;
    8.27 +        int_result = sqlite3_step(_sql);
    8.28 +        assert(int_result == SQLITE_ROW);
    8.29 +        if (int_result == SQLITE_ROW)
    8.30 +            _result = sqlite3_column_int(_sql, 0);
    8.31 +        sqlite3_finalize(_sql);
    8.32 +        if (int_result != SQLITE_ROW)
    8.33 +            return PEP_UNKNOWN_ERROR;
    8.34 +
    8.35 +    ||
    8.36 +}
    8.37 +