rendered paste bodystatic pk_err_t obtain_chunk(struct pk_state *state, unsigned chunk,
void *tag, void **buf, unsigned *len)
{
pk_err_t ret;
void *local_buf;
gchar *device_buf;
gchar *ftag;
local_buf = g_malloc(state->parcel->chunksize);
/* Read the chunk from the local cache. Don't check the
tag, since decrypt will check the key.
length is not zero only when chunk is present in local cache */
if (*len && !_cache_read_chunk(state, chunk, local_buf, *len, NULL)) {
*buf = local_buf;
return PK_SUCCESS;
}
/* Get chunk from hoard cache */
if (!hoard_get_chunk(state, tag, local_buf, len)) {
*buf = local_buf;
return PK_SUCCESS;
}
ftag = iu_bin2hex(tag, state->parcel->hashlen);
pk_log(LOG_CHUNK, "Tag %s not in hoard cache", ftag);
g_free(ftag);
/* Get chunk from horatio */
if (!device_get_chunk(state, tag, state->parcel->hashlen, &device_buf,
len)) {
*buf = device_buf;
g_free(local_buf);
return PK_SUCCESS;
}
/* Get chunk from server */
ret = transport_fetch_chunk(state->cpool, local_buf, chunk,
tag, len, TRUE);
*buf = local_buf;
return ret;
}
pk_err_t device_get_chunk(struct pk_state *state, void *tag, unsigned taglen,
gchar **buf, unsigned *filelen)
{
pk_err_t ret;
struct query *qry;
gboolean retry;
if (state->conf->device_path == NULL) {
return PK_NOTFOUND;
}
again:
if (!begin(state->db)) {
return PK_SQLERR;
}
if (!query(&qry, state->db, "SELECT id FROM horatio.chunks "
"WHERE tag == ?", "b",
tag, taglen)) {
sql_log_err(state->db, "Error searching for chunk on device\n");
ret = PK_SQLERR;
goto bad;
}
if (query_has_row(state->db)) {
ret = _device_read_chunk(state, tag, taglen, buf, filelen);
} else {
printf("Chunk not found on device\n");
ret = PK_NOTFOUND;
}
query_free(qry);
return ret;
bad:
retry = query_busy(state->db);
rollback(state->db);
if (retry) {
query_backoff(state->db);
goto again;
}
return ret;
}