- k5_mutex_lock(&id->lock);
-
- switch(rc_store(context, id, rep, now, FALSE)) {
- case CMP_MALLOC:
- k5_mutex_unlock(&id->lock);
- return KRB5_RC_MALLOC;
- case CMP_REPLAY:
- k5_mutex_unlock(&id->lock);
- return KRB5KRB_AP_ERR_REPEAT;
- case 0: break;
- default: /* wtf? */ ;
- }
- t = (struct dfl_data *)id->data;
-#ifndef NOIOSTUFF
- ret = krb5_rc_io_store(context, t, rep);
- if (ret) {
- k5_mutex_unlock(&id->lock);
- return ret;
- }
-#endif
- /* Shall we automatically expunge? */
- if (t->nummisses > t->numhits + EXCESSREPS)
- {
- ret = krb5_rc_dfl_expunge_locked(context, id);
- k5_mutex_unlock(&id->lock);
- return ret;
- }
-#ifndef NOIOSTUFF
- else
- {
- if (krb5_rc_io_sync(context, &t->d)) {
- k5_mutex_unlock(&id->lock);
- return KRB5_RC_IO;
- }
- }
-#endif
- k5_mutex_unlock(&id->lock);
- return 0;
-}
-
-static krb5_error_code
-krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id)
-{
- struct dfl_data *t = (struct dfl_data *)id->data;
-#ifdef NOIOSTUFF
- unsigned int i;
- struct authlist **q;
- struct authlist **qt;
- struct authlist *r;
- struct authlist *rt;
- krb5_timestamp now;
-
- if (krb5_timestamp(context, &now))
- now = 0;
-
- for (q = &t->a; *q; q = qt) {
- qt = &(*q)->na;
- if (alive(now, &(*q)->rep, t->lifespan) == CMP_EXPIRED) {
- free((*q)->rep.client);
- free((*q)->rep.server);
- if ((*q)->rep.msghash)
- free((*q)->rep.msghash);
- free(*q);
- *q = *qt; /* why doesn't this feel right? */
- }
- }
- for (i = 0; i < t->hsize; i++)
- t->h[i] = (struct authlist *) 0;
- for (r = t->a; r; r = r->na) {
- i = hash(&r->rep, t->hsize);
- rt = t->h[i];
- t->h[i] = r;
- r->nh = rt;
- }
- return 0;
-#else
- struct authlist *q;
- char *name;
- krb5_error_code retval = 0;
- krb5_rcache tmp;
- krb5_deltat lifespan = t->lifespan; /* save original lifespan */
-
- if (! t->recovering) {
- name = t->name;
- t->name = 0; /* Clear name so it isn't freed */
- (void) krb5_rc_dfl_close_no_free(context, id);
- retval = krb5_rc_dfl_resolve(context, id, name);
- free(name);
- if (retval)
- return retval;
- retval = krb5_rc_dfl_recover_locked(context, id);
- if (retval)
- return retval;
- t = (struct dfl_data *)id->data; /* point to recovered cache */
- }
-
- retval = krb5_rc_resolve_type(context, &tmp, "dfl");
- if (retval)
- return retval;
- retval = krb5_rc_resolve(context, tmp, 0);
- if (retval)
- goto cleanup;
- retval = krb5_rc_initialize(context, tmp, lifespan);
- if (retval)
- goto cleanup;
- for (q = t->a; q; q = q->na) {
- if (krb5_rc_io_store(context, (struct dfl_data *)tmp->data, &q->rep)) {
- retval = KRB5_RC_IO;
- goto cleanup;
- }
- }
- /* NOTE: We set retval in case we have an error */
- retval = KRB5_RC_IO;
- if (krb5_rc_io_sync(context, &((struct dfl_data *)tmp->data)->d))
- goto cleanup;
- if (krb5_rc_io_sync(context, &t->d))
- goto cleanup;
- if (krb5_rc_io_move(context, &t->d, &((struct dfl_data *)tmp->data)->d))
- goto cleanup;
- retval = 0;
-cleanup:
- (void) krb5_rc_dfl_close(context, tmp);
- return retval;
-#endif