int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, ENGINE *e, const int *nids, int num_nids, int setdefault) { int ret = 0, added = 0; ENGINE_PILE tmplate, *fnd; CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); if(!(*table)) added = 1; if(!int_table_check(table, 1)) goto end; if(added) /* The cleanup callback needs to be added */ engine_cleanup_add_first(cleanup); while(num_nids--) { tmplate.nid = *nids; fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate); if(!fnd) { fnd = OPENSSL_malloc(sizeof(ENGINE_PILE)); if(!fnd) goto end; fnd->uptodate = 1; fnd->nid = *nids; fnd->sk = sk_ENGINE_new_null(); if(!fnd->sk) { OPENSSL_free(fnd); goto end; } fnd->funct = NULL; (void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd); } /* A registration shouldn't add duplciate entries */ (void)sk_ENGINE_delete_ptr(fnd->sk, e); /* if 'setdefault', this ENGINE goes to the head of the list */ if(!sk_ENGINE_push(fnd->sk, e)) goto end; /* "touch" this ENGINE_PILE */ fnd->uptodate = 0; if(setdefault) { if(!engine_unlocked_init(e)) { ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER, ENGINE_R_INIT_FAILED); goto end; } if(fnd->funct) engine_unlocked_finish(fnd->funct, 0); fnd->funct = e; fnd->uptodate = 1; } nids++; } ret = 1; end: CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); return ret; }
static int int_engine_init(ENGINE *e) { if (!ENGINE_init(e)) return 0; if (!initialized_engines) initialized_engines = sk_ENGINE_new_null(); if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e)) { ENGINE_finish(e); return 0; } return 1; }