/* Forget a fingerprint (so long as it's not the active one. If it's a * fingerprint_root, forget the whole context (as long as * and_maybe_context is set, and it's PLAINTEXT). Also, if it's not * the fingerprint_root, but it's the only fingerprint, and we're * PLAINTEXT, forget the whole context if and_maybe_context is set. */ void otrl_context_forget_fingerprint(Fingerprint *fprint, int and_maybe_context) { ConnContext *context = fprint->context; if (fprint == &(context->fingerprint_root)) { if (context->msgstate == OTRL_MSGSTATE_PLAINTEXT && and_maybe_context) { otrl_context_forget(context); } } else { if (context->msgstate != OTRL_MSGSTATE_PLAINTEXT || context->active_fingerprint != fprint) { free(fprint->fingerprint); free(fprint->trust); *(fprint->tous) = fprint->next; if (fprint->next) { fprint->next->tous = fprint->tous; } free(fprint); if (context->msgstate == OTRL_MSGSTATE_PLAINTEXT && context->fingerprint_root.next == NULL && and_maybe_context) { /* We just deleted the only fingerprint. Forget the * whole thing. */ otrl_context_forget(context); } } } }
/* Forget all the contexts in a given OtrlUserState. */ void otrl_context_forget_all(OtrlUserState us) { while (us->context_root) { otrl_context_force_plaintext(us->context_root); otrl_context_forget(us->context_root); } }
/* Forget a whole context, so long as it's PLAINTEXT. If a context has child * instances, don't remove this instance unless children are also all in * PLAINTEXT state. In this case, the children will also be removed. * Returns 0 on success, 1 on failure. */ int otrl_context_forget(ConnContext *context) { if (context->msgstate != OTRL_MSGSTATE_PLAINTEXT) return 1; if (context->their_instance == OTRL_INSTAG_MASTER) { ConnContext *c_iter; for (c_iter = context; c_iter && c_iter->m_context == context->m_context; c_iter = c_iter->next) { if (c_iter->msgstate != OTRL_MSGSTATE_PLAINTEXT) return 1; } c_iter = context->next; while (c_iter && c_iter->m_context == context->m_context) { if (!otrl_context_forget(c_iter)) { c_iter = context->next; } else { return 1; } } } /* Just to be safe, force to plaintext. This also frees any * extraneous data lying around. */ otrl_context_force_plaintext(context); /* First free all the Fingerprints */ while(context->fingerprint_root.next) { otrl_context_forget_fingerprint(context->fingerprint_root.next, 0); } /* Now free all the dynamic info here */ free(context->username); free(context->accountname); free(context->protocol); free(context->smstate); context->username = NULL; context->accountname = NULL; context->protocol = NULL; context->smstate = NULL; /* Free the application data, if it exists */ if (context->app_data && context->app_data_free) { (context->app_data_free)(context->app_data); context->app_data = NULL; } /* Fix the list linkages */ *(context->tous) = context->next; if (context->next) { context->next->tous = context->tous; } free(context); return 0; }
/* Forget all the contexts in a given OtrlUserState. */ void otrl_context_forget_all(OtrlUserState us) { ConnContext *c_iter; for (c_iter = us->context_root; c_iter; c_iter = c_iter->next) { otrl_context_force_plaintext(c_iter); } while (us->context_root) { otrl_context_forget(us->context_root); } }